Android开发 - Matrix 处理图像变换解析

Matrix 是什么

  • Matrix 是一个用于处理图像变换,它可以对图像进行缩放旋转平移和倾斜等操作。通俗来讲,Matrix 就像是一个数学公式,用来定义如何改变图像的位置形状或者方向

Matrix 的主要功能

  • 缩放(Scale):可以改变图片的大小,比如放大或缩小

  • 旋转(Rotate):可以将图片绕某个点旋转一定的角度

  • 平移(Translate):可以移动图片的位置

  • 倾斜(Skew):可以让图片变形,比如将图片斜着拉长

  • 这些操作都可以通过修改 Matrix 来实现,Matrix 是一个 3x3 的矩阵,表示对图像的变换方式

主要方法解析

  • matrix.set(Matrix matrix):将一个矩阵的值复制到当前矩阵

    Matrix matrix1 = new Matrix();
    Matrix matrix2 = new Matrix();
    matrix1.setScale(2f, 2f);
    matrix2.set(matrix1);  // 把 matrix1 的值赋给 matrix2
    
    • 参数解析
      • matrix当前 matrix 对象
  • matrix.setScale(float sx, float sy)缩放图片

    Matrix matrix = new Matrix();
    matrix.setScale(2f, 2f);  // 把图片放大两倍
    
    • 参数解析
      • sx横向缩放比例;值大于 1 表示放大,值小于 1 表示缩小
      • sy纵向缩放比例;值大于 1 表示放大,值小于 1 表示缩小
  • matrix.setRotate(float degrees)旋转图片

    Matrix matrix = new Matrix();
    matrix.setRotate(45);  // 旋转45度
    
    • 参数解析
      • degrees旋转的角度正数表示顺时针旋转负数表示逆时针旋转
  • matrix.setTranslate(float dx, float dy)移动图片

    Matrix matrix = new Matrix();
    matrix.setTranslate(100, 200);  // 将图片向右移动100像素,向下移动200像素
    
    • 参数解析
      • dx横向移动距离
      • dy纵向移动距离
  • matrix.setSkew(float kx, float ky)倾斜图片;它可以让图片产生类似于拉长拉伸的效果

    Matrix matrix = new Matrix();
    matrix.setSkew(0.5f, 0.2f);  // 使图片横向倾斜0.5,纵向倾斜0.2
    
    • 参数解析
      • kx横向倾斜系数
      • ky纵向倾斜系数
  • matrix.postTranslate(float dx, float dy):基于现有的变换再做移动操作

    Matrix matrix = new Matrix();
    matrix.setScale(2f, 2f);
    matrix.postTranslate(100f, 100f);  // 先缩放再平移
    
    • 参数解析
      • dx追加的横向移动距离
      • dy追加的纵向移动距离
  • matrix.postScale(float sx, float sy):基于当前变换追加缩放操作

    Matrix matrix = new Matrix();
    matrix.setTranslate(50f, 50f);
    matrix.postScale(2f, 2f);  // 先平移,再缩放
    
    • 参数解析
      • kx追加的横向缩放系数
      • ky追加的纵向缩放系数
  • matrix.postRotate(float degrees):基于现有的矩阵进行旋转操作

    Matrix matrix = new Matrix();
    matrix.setScale(1.5f, 1.5f);
    matrix.postRotate(45);  // 先缩放再旋转
    
    • 参数解析
      • degrees追加的旋转角度
  • matrix.postSkew(float kx, float ky):在已有的矩阵操作上追加倾斜操作

    Matrix matrix = new Matrix();
    matrix.setScale(2f, 2f);
    matrix.postSkew(0.5f, 0.5f);  // 先缩放再倾斜
    
    • 参数解析
      • kx追加的横向倾斜系数
      • ky追加的纵向倾斜系数
  • matrix.invert(Matrix inverse):用于求当前矩阵逆矩阵,如果当前矩阵可逆的,会将逆矩阵存储到 inverse 参数中,返回 true,否则返回 false

    Matrix matrix = new Matrix();
    matrix.setScale(2f, 2f);
    Matrix inverseMatrix = new Matrix();
    boolean isInvertible = matrix.invert(inverseMatrix);  // 计算逆矩阵
    
    • 参数解析
      • inverse:用于得出的 当前matrix 对象 是否为逆矩阵
  • matrix.mapRect(RectF rect):对矩形进行变换矩形会根据当前矩阵进行缩放平移旋转等变换

    Matrix matrix = new Matrix();
    matrix.setScale(2f, 2f);
    RectF rect = new RectF(0, 0, 100, 100);
    matrix.mapRect(rect);  // 变换后的矩形坐标会改变
    
    • 参数解析
      • rect:接收一个重定矩形RectF 对象
  • matrix.mapRect(RectF rect):将当前的矩阵重置为单位矩阵单位矩阵初始状态,表示没有任何变换

    Matrix matrix = new Matrix();
    matrix.setScale(2f, 2f);
    matrix.reset();  // 重置为单位矩阵
    
  • matrix.preTranslate(float dx, float dy):在已有矩阵操作之前进行平移

    Matrix matrix = new Matrix();
    matrix.setScale(2f, 2f);
    matrix.preTranslate(50f, 50f);  // 先平移再缩放
    
      • 参数解析
        • dx横向移动距离
        • dy纵向移动距离
  • matrix.preScale(float sx, float sy):在已有矩阵操作之前进行缩放

    Matrix matrix = new Matrix();
    matrix.setScale(2f, 2f);
    matrix.preTranslate(50f, 50f);  // 先平移再缩放
    
      • 参数解析
        • sx横向缩放比例
        • sy纵向缩放比例
  • matrix.preRotate(float degrees):在已有矩阵操作之前进行旋转

    Matrix matrix = new Matrix();
    matrix.setTranslate(100f, 100f);
    matrix.preRotate(45);  // 先旋转再平移
    
      • 参数解析
        • degrees旋转的角度
  • matrix.preSkew(float kx, float ky):在已有矩阵操作之前进行倾斜

    Matrix matrix = new Matrix();
    matrix.setScale(2f, 2f);
    matrix.preSkew(0.5f, 0.5f);  // 先倾斜再缩放
    
    • 参数解析
      • kx横向倾斜系数
      • ky纵向倾斜系数
  • matrix.setConcat(Matrix a, Matrix b):将两个矩阵相乘,并将结果赋给当前矩阵。相当于 Matrix乘法运算

    Matrix matrix1 = new Matrix();
    matrix1.setScale(2f, 2f);
    
    Matrix matrix2 = new Matrix();
    matrix2.setRotate(45);
    
    Matrix result = new Matrix();
    result.setConcat(matrix1, matrix2);  // 将 matrix1 和 matrix2 组合
    
    • 参数解析
      • a要组合的第一个 Matrix 对象
      • b要组合的第二个 Matrix 对象
  • matrix.setPolyToPoly(float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount):将源点数组 src 变换为目标点数组 dst。可以指定多少个点参变换,允许更复杂几何操作。主要将源多边形多个点通过变换映射到目标多边形相应点。通过指定多个点,Matrix 会计算出从源点目标点变换矩阵

    Matrix matrix = new Matrix();
    float[] src = {0f, 0f, 100f, 0f};   // 源多边形的两个点:两个点为 (0, 0) 和 (100, 0)
    float[] dst = {0f, 0f, 150f, 50f};  // 目标多边形的两个点:目标点为 (0, 0) 和 (150, 50
    matrix.setPolyToPoly(src, 0, dst, 0, 2);  // 使用两个点进行变换。srcIndex 和 dstIndex 都为 0,表示从第一个点开始使用。pointCount 为 2,表示我们使用两个点来计算变换
    
    • 参数解析
      • src源点数组,包含源多边形所有点坐标。这个数组顺序存储坐标信息数组的长度应该是 2 * nn点的数量每个点两个连续的浮点数表示,分别是 x 和 y 坐标。例如:src = {x1, y1, x2, y2, x3, y3, ...}
      • srcIndex源点数组的起始索引,从这个位置开始读取源点数据。例如:如果 srcIndex = 0,则从 src 数组第一个点开始使用;如果 srcIndex = 2,则从数组中的第三个浮点数(即第二个点的 x 坐标)开始使用
      • dst目标点数组,包含目标多边形所有点的坐标。这个数组src 类似,也按顺序存储目标多边形的坐标。Matrix 会根据这些计算变换矩阵,将源多边形映射到这些目标点
      • dstIndex目标点数组的起始索引,从这个位置开始读取目标点数据。例如:如果 dstIndex = 0,则从 dst 数组第一个点开始使用;如果 dstIndex = 2,则从数组中的第三个浮点数(即第二个点的 x 坐标)开始使用
      • pointCount参与变换的点的数量pointCount 决定了 srcdst 中的有多少个会被用于计算变换矩阵最多支持 4 个点的变换,具体的点数决定了变换的复杂程度
        • 1个点:只能实现平移
        • 2个点:可以实现平移缩放(单轴或双轴缩放)
        • 3个点:可以实现平移缩放旋转
        • 4个点:可以实现平移缩放旋转任意形变(透视变换)

如何使用 Matrix

  • Matrix 一般和 CanvasBitmap 结合使用,可以将这些变换应用到图片或绘制的元素上。例如,在自定义控件中绘制一个经过旋转或缩放的图像时,可以使用 Matrix 来对图像进行变换

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Matrix matrix = new Matrix();
        matrix.setScale(1.5f, 1.5f);  // 对图片进行1.5倍放大
        canvas.drawBitmap(bitmap, matrix, null);  // 绘制变换后的图片
    }
    

总结

  • Matrix 本质上是一个数学工具,用于图像的几何变换

  • 通过操作 Matrix,可以对图片进行缩放、旋转、移动、倾斜等操作,改变其在屏幕上的显示方式

posted @ 2024-09-05 18:35  阿俊学JAVA  阅读(3)  评论(0编辑  收藏  举报