Android中的Matrix:是什么、矩阵类型与变换操作

作者: IT Sectr 发布日期: 2026-07-22 阅读时间: 9 分钟

Matrix —— 是Android SDK中的一个类(android.graphics.Matrix),通过3×3矩阵表示仿射变换。它用于图形对象的变换——移动、缩放、旋转和倾斜。根据Android Developers Documentation (2026),Matrix是在Canvas、Bitmap和Drawable中进行变换操作的主要工具,在自定义绘制时提供精确的坐标控制。

要点

  • Matrix —— 用于3×3矩阵的仿射和透视变换的Android类
  • 仿射操作:translate(平移)、scale(缩放)、rotate(旋转)和skew(倾斜)
  • Matrix通过setPolyToPoly支持透视(projection)变换
  • 操作的应用顺序很重要 —— Matrix.concat执行顺序乘法
  • Matrix应用于Android图形中的Canvas、Bitmap、RectF、PointF和Path

Android中的Matrix是什么?

Matrix(android.graphics.Matrix)—— 是Android SDK中的一个类,表示用于变换二维坐标的数学3×3矩阵。Matrix是Android中所有图形变换的基本构建块——从Canvas的平移和缩放到Bitmap的复杂透视变形。

与iOS(使用单独的CGAffineTransform(仿射)和CATransform3D(3D)结构)不同,Android将仿射和透视变换合并到一个Matrix类中。3×3矩阵既可以表示标准的仿射操作(最后一行[0, 0, 1]),也可以表示最后一行包含任意值时的透视变形。这提供了更大的灵活性,但需要理解矩阵数学。

Matrix与Canvas API紧密集成。当开发者调用canvas.translate()canvas.scale()canvas.rotate()时,这些方法内部会修改图形上下文的矩阵。可以通过canvas.getMatrix()获取Canvas的当前矩阵,并通过canvas.setMatrix()canvas.concat()手动应用自定义矩阵。

Matrix变换的类型

Matrix支持四种基本的仿射变换类型:translate、scale、rotate、skew(倾斜)。每种类型都有前乘(pre)、后乘(post)和设置(set)方法。preTranslate和postTranslate之间的区别在于矩阵乘法的顺序,这会影响组合时的最终变换。

操作方法参数描述
TranslatesetTranslate / preTranslate / postTranslatedx, dy沿X和Y轴平移
ScalesetScale / preScale / postScalesx, sy, px, py带参考点的缩放
RotatesetRotate / preRotate / postRotatedegrees, px, py围绕参考点旋转
SkewsetSkew / preSkew / postSkewkx, ky沿轴倾斜(滑动)

Translate —— 平移

Translate将所有点的位置改变给定的dx、dy偏移量。正的dx向右移动,dy——向下(在Android屏幕坐标系中,Y轴向下)。Translate不改变对象的形状——只改变其位置。这是最简单、最常用的元素定位操作。

Scale —— 缩放

Scale以sx(沿X轴)和sy(沿Y轴)的系数改变对象的大小。参数px、py指定缩放参考点(pivot point)。如果未指定px、py,则相对于坐标原点(0, 0)进行缩放。当sx = sy时,对象均匀缩放。负值创建镜像。

Rotate —— 旋转

Rotate将对象围绕参考点(px, py)旋转给定角度(以度为单位)。正角度值对应顺时针旋转(与iOS/macOS不同,在iOS/macOS中正角度为逆时针)。如果未指定px、py,则绕坐标原点旋转。

Skew —— 倾斜

Skew(滑动)通过沿X轴(kx)或Y轴(ky)倾斜来变形对象。值1.0倾斜45度。Skew用于创建倾斜效果、模拟三维视图(伪3D)和透视变形。

3×3矩阵的结构

Matrix将3×3矩阵的元素存储在一个由9个浮点值组成的内部数组中(float[9])。存储顺序为列主序(column-major),与标准数学表示一致。通过常量访问各个元素:Matrix.MSCALE_XMatrix.MSKEW_YMatrix.MTRANS_X等。

矩阵元素

矩阵的组织方式如下:前两列(MSCALE_X、MSKEW_X、MSKEW_Y、MSCALE_Y)负责缩放、旋转和倾斜。第三列(MTRANS_X、MTRANS_Y、MPERSP_2)—— 负责平移和透视。对于仿射变换,MPERSP_0和MPERSP_1等于0,MPERSP_2等于1。

使用getValues(float[] values)获取矩阵值,该方法填充一个包含9个元素的数组。设置使用setValues(float[] values)。这允许直接操作矩阵以实现超出标准translate、scale、rotate和skew方法的复杂自定义变换。

检查矩阵类型

Matrix提供了几种分类当前状态的方法。isIdentity()检查矩阵是否为单位矩阵。isAffine()—— 是否仅包含仿射变换(MPERSP_0 = 0, MPERSP_1 = 0, MPERSP_2 = 1)。这些检查对于优化很有用:如果矩阵是单位矩阵,则可以跳过变换。

Matrix的基本操作

Matrix支持几类操作:设置(set)、前乘(pre)、后乘(post)、连接(concat)、求逆(invert)和映射(map)。每个类别在构建复杂变换时解决其自己的任务。

Pre和Post操作

preTranslate将当前矩阵左乘平移矩阵:result = translate × currentpostTranslate右乘:result = current × translate。区别在于应用顺序:pre操作在当前变换之前应用,post操作在之后应用。preScale、postScale、preRotate、postRotate以及preSkew、postSkew的工作方式类似。

求逆和连接

invert(Matrix inverse)计算逆矩阵。如果源矩阵是退化的(行列式为零),返回false。concat(Matrix other)将当前矩阵乘以传入的矩阵:set = set × other。对于相反顺序,使用setConcat(other, this)

Map —— 应用于点和矩形

mapRect(RectF rect)变换矩形并将结果返回到新的RectF中。mapPoints(float[] dst, float[] src)变换点数组。mapVectors(float[] dst, float[] src)变换向量——不考虑平移(translate)。mapRect用于计算变换后的边界框。

在Canvas和Bitmap中的应用

Matrix在Android图形的两个关键场景中被积极使用:Canvas变换和Bitmap变换。在这两种情况下,Matrix决定了图形输出如何被改变。

通过Matrix进行Canvas变换

Canvas提供canvas.setMatrix(matrix)方法用于完全替换当前矩阵,以及canvas.concat(matrix)方法用于将当前变换乘以传入的矩阵。应用Matrix后,所有后续的绘制——drawBitmap、drawRect、drawPath调用——都在变换后的坐标系中执行。Canvas还通过save()restore()维护自己的保存状态栈。

通过Matrix进行Bitmap变换

Bitmap.createBitmap(Bitmap source, int x, int y, int width, int height, Matrix matrix, boolean filter)创建一个应用了给定变换的新Bitmap。这是一个强大的工具,可以在不丢失原始Bitmap的情况下创建缩放、旋转或变形的图像副本。参数filter控制像素插值时的平滑处理。

setPolyToPoly —— 透视变换

setPolyToPoly(float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount)—— Matrix的独特功能,在CGAffineTransform中没有直接对应。它计算一个将给定点从一个多边形变换到另一个多边形的矩阵。当pointCount = 4时,创建完整的透视(projective)变换,允许应用带有透视变形的Bitmap。

Kotlin代码示例

让我们看看在Kotlin的Android应用中使用Matrix进行图形变换的实际示例

基本仿射变换

示例创建一个用于组合变换的Matrix:平移(100, 50)、缩放1.5倍和旋转45度。在preRotate和preScale之后使用postTranslate会改变操作的应用顺序。

kotlin
val matrix = Matrix()
matrix.preScale(1.5f, 1.5f)
matrix.preRotate(45f)
matrix.postTranslate(100f, 50f)

// 应用于点
val pts = floatArrayOf(0f, 0f, 100f, 100f)
matrix.mapPoints(pts)

// 应用于矩形
val rect = RectF(0f, 0f, 200f, 100f)
matrix.mapRect(rect)

使用save和restore的Canvas变换

示例演示了在onDraw中将Matrix应用于Canvas以围绕其中心旋转和缩放圆形。保存和恢复Canvas状态确保变换不会影响后续的绘制元素。

kotlin
override fun onDraw(canvas: Canvas) {
    super.onDraw(canvas)

    val cx = width / 2f
    val cy = height / 2f
    val radius = 100f

    canvas.save()
    val matrix = Matrix()
    matrix.postTranslate(cx, cy)
    matrix.postRotate(30f)
    matrix.postScale(1.2f, 1.2f)
    canvas.concat(matrix)

    val paint = Paint().apply {
        color = Color.BLUE
        style = Paint.Style.FILL
    }
    canvas.drawCircle(0f, 0f, radius, paint)
    canvas.restore()
}

通过setPolyToPoly进行透视变形

示例使用setPolyToPoly创建Bitmap的透视变形。四个源点(原始矩形的角点)被映射到四个形成梯形的目标点。结果——在空间中倾斜的图像效果。

kotlin
fun applyPerspective(
    bitmap: Bitmap,
    skew: Float
): Bitmap {
    val w = bitmap.width.toFloat()
    val h = bitmap.height.toFloat()

    val src = floatArrayOf(0f, 0f, w, 0f,
                         0f, h, w, h)
    val dst = floatArrayOf(skew, 0f, w - skew, 0f,
                         0f, h, w, h)

    val matrix = Matrix()
    matrix.setPolyToPoly(src, 0, dst, 0, 4)

    return Bitmap.createBitmap(
        bitmap, 0, 0,
        w.toInt(), h.toInt(),
        matrix, true
    )
}

常见问题

Android中Matrix和Camera有什么区别?

Matrix通过一个3×3矩阵处理二维仿射和透视变换。Camera(android.graphics.Camera)—— 是一个更高层次的类,模拟三维相机:创建3D旋转然后将结果投影到2D Matrix中。Camera内部使用Matrix。

如何将Bitmap旋转90度?

创建一个带有postRotate(90f)的Matrix并将其传递给Bitmap.createBitmap(original, 0, 0, w, h, matrix, true)。请注意,旋转90度后,结果的宽度和高度会互换。对于任意角度的旋转,可能需要裁剪以避免空白区域。

如何获得Matrix的逆变换?

使用matrix.invert(resultMatrix)。如果求逆成功,该方法返回true,并将逆矩阵写入resultMatrix。如果矩阵是退化的(例如,零缩放),求逆可能失败。始终检查返回值。

pre和post操作有什么区别?

pre左乘新的变换:result = operation × current —— 操作在当前变换之前应用。post右乘:result = current × operation —— 操作在当前变换之后应用。对于preRotate + postTranslate序列:先旋转,后平移。

可以在Compose中使用Matrix吗?

可以,Matrix在Jetpack Compose中通过android.graphics.Matrix类与Canvas Compose交互使用。在Compose中,graphicsLayer可用于变换(scale、rotationX、translationX等),但对于复杂的Bitmap变换,Matrix在drawWithContentdrawBehind代码中应用。

总结

  • Matrix —— 用于3×3矩阵的仿射和透视变换的Android类
  • 四种基本类型:translate(平移)、scale(缩放)、rotate(旋转)、skew(倾斜)
  • pre/post操作控制应用顺序:pre —— 在当前变换之前,post —— 在当前变换之后
  • setPolyToPoly —— 用于计算4对点的透视变换的独特函数
  • Matrix通过concat应用于Canvas,通过createBitmap与Matrix应用于Bitmap,通过mapPoints应用于点
  • invert计算逆变换,对退化矩阵返回false
  • isAffineisIdentity有助于分类矩阵状态以进行优化

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读