Matrix trong Android: nó là gì, các loại ma trận và làm việc với biến đổi

Tác giả: IT Sectr Đã đăng: 2026-07-22 Thời gian đọc: 9 phút

Matrix — là một lớp từ Android SDK (android.graphics.Matrix) biểu diễn phép biến đổi affine thông qua ma trận 3×3. Nó được sử dụng để biến đổi các đối tượng đồ họa — di chuyển, thay đổi kích thước, xoay và nghiêng. Theo Tài liệu dành cho nhà phát triển Android (2026), Matrix là công cụ chính để làm việc với các phép biến đổi trong Canvas, Bitmap và Drawable, cung cấp khả năng kiểm soát tọa độ chính xác khi vẽ tùy chỉnh.

Điểm chính

  • Matrix — lớp Android cho các phép biến đổi affine và phối cảnh với ma trận 3×3
  • Các thao tác affine: translate (di chuyển), scale (thay đổi kích thước), rotate (xoay) và skew (nghiêng)
  • Matrix hỗ trợ các phép biến đổi chiếu thông qua setPolyToPoly
  • Thứ tự các thao tác rất quan trọng — Matrix.concat thực hiện phép nhân tuần tự
  • Matrix được áp dụng cho Canvas, Bitmap, RectF, PointF và Path trong đồ họa Android

Matrix trong Android là gì?

Matrix (android.graphics.Matrix) — là một lớp SDK Android biểu diễn ma trận toán học 3×3 được sử dụng để biến đổi các tọa độ hai chiều. Matrix là khối xây dựng cơ bản cho mọi biến đổi đồ họa trong Android — từ di chuyển và thay đổi kích thước Canvas đến các biến dạng phối cảnh phức tạp của Bitmap.

Không giống như iOS, sử dụng các cấu trúc riêng biệt CGAffineTransform (affine) và CATransform3D (3D), Android kết hợp các phép biến đổi affine và phối cảnh trong một lớp Matrix duy nhất. Ma trận 3×3 cho phép biểu diễn cả các thao tác affine tiêu chuẩn (hàng cuối [0, 0, 1]) và các biến dạng phối cảnh khi hàng cuối chứa các giá trị tùy ý. Điều này mang lại sự linh hoạt hơn nhưng đòi hỏi sự hiểu biết về toán học ma trận.

Matrix được tích hợp chặt chẽ với Canvas API. Khi nhà phát triển gọi canvas.translate(), canvas.scale() hoặc canvas.rotate(), các phương thức này sẽ sửa đổi ma trận của ngữ cảnh đồ họa. Bạn có thể lấy ma trận Canvas hiện tại qua canvas.getMatrix() và áp dụng thủ công ma trận tùy chỉnh qua canvas.setMatrix() hoặc canvas.concat().

Các loại biến đổi Matrix

Matrix hỗ trợ bốn loại biến đổi affine cơ bản: translate, scale, rotate, skew (nghiêng). Mỗi loại có các phương thức cho pre-nhân (pre), post-nhân (post) và thiết lập (set). Sự khác biệt giữa preTranslate và postTranslate nằm ở thứ tự nhân ma trận, ảnh hưởng đến biến đổi cuối cùng khi kết hợp các thao tác.

Thao tácPhương thứcTham sốMô tả
Di chuyểnsetTranslate / preTranslate / postTranslatedx, dyDịch chuyển dọc theo trục X và Y
Thay đổi kích thướcsetScale / preScale / postScalesx, sy, px, pyThay đổi kích thước với điểm neo
XoaysetRotate / preRotate / postRotatedegrees, px, pyXoay quanh điểm neo
NghiêngsetSkew / preSkew / postSkewkx, kyNghiêng (cắt) dọc theo các trục

Di chuyển — dịch chuyển

Translate thay đổi vị trí của tất cả các điểm bằng một độ dịch chuyển dx, dy. dx dương dịch sang phải, dy — xuống dưới (trong hệ tọa độ màn hình Android, trục Y hướng xuống dưới). Translate không thay đổi hình dạng của đối tượng — chỉ vị trí của nó. Đây là thao tác đơn giản nhất và được sử dụng nhiều nhất để định vị các phần tử.

Thay đổi kích thước — phóng to/thu nhỏ

Scale thay đổi kích thước của đối tượng với các hệ số sx (dọc theo X) và sy (dọc theo Y). Các tham số px, py chỉ định điểm neo cho việc thay đổi kích thước. Nếu px, py không được chỉ định, việc thay đổi kích thước được thực hiện tương đối so với gốc tọa độ (0, 0). Khi sx = sy, đối tượng thay đổi kích thướbc đồng đều. Các giá trị âm tạo ra sự phản chiếu.

Xoay — xoay

Rotate xoay một đối tượng theo một góc cho trước (tính bằng độ) quanh điểm neo (px, py). Giá trị độ dương tương ứng với xoay theo chiều kim đồng hồ (khác với iOS/macOS, nơi góc dương là ngược chiều kim đồng hồ). Nếu px, py không được thiết lập, việc xoay được thực hiện quanh gốc tọa độ.

Nghiêng — nghiêng

Skew (cắt) làm biến dạng đối tượng bằng cách nghiêng nó dọc theo trục X (kx) hoặc trục Y (ky). Giá trị 1.0 nghiêng ở góc 45 độ. Skew được sử dụng để tạo hiệu ứng nghiêng, giao diện giả 3D và biến dạng phối cảnh.

Cấu trúc ma trận 3×3

Matrix lưu trữ các phần tử 3×3 của nó trong một mảng nội bộ gồm 9 giá trị dấu phẩy động (float[9]). Thứ tự lưu trữ là column-major (theo cột), phù hợp với biểu diễn toán học tiêu chuẩn. Truy cập vào các phần tử riêng lẻ được thực hiện thông qua các hằng số: Matrix.MSCALE_X, Matrix.MSKEW_Y, Matrix.MTRANS_X và các hằng khác.

Các phần tử của ma trận

Ma trận được tổ chức như sau: hai cột đầu tiên (MSCALE_X, MSKEW_X, MSKEW_Y, MSCALE_Y) xử lý việc thay đổi kích thước, xoay và nghiêng. Cột thứ ba (MTRANS_X, MTRANS_Y, MPERSP_2) xử lý việc di chuyển và phối cảnh. Đối với các phép biến đổi affine, MPERSP_0 và MPERSP_1 là 0, và MPERSP_2 là 1.

Để lấy giá trị ma trận, hãy sử dụng getValues(float[] values), phương thức này điền vào một mảng gồm 9 phần tử. Để thiết lập, hãy sử dụng setValues(float[] values). Điều này cho phép thao tác trực tiếp trên ma trận cho các biến đổi tùy chỉnh phức tạp vượt ra ngoài các phương thức translate, scale, rotate và skew tiêu chuẩn.

Kiểm tra loại ma trận

Matrix cung cấp một số phương thức để phân loại trạng thái hiện tại. isIdentity() kiểm tra xem ma trận có phải là ma trận đơn vị không. isAffine() kiểm tra xem nó có chỉ chứa các phép biến đổi affine hay không (MPERSP_0 = 0, MPERSP_1 = 0, MPERSP_2 = 1). Các kiểm tra này hữu ích cho việc tối ưu hóa: nếu ma trận là đơn vị, có thể bỏ qua biến đổi.

Các thao tác cơ bản với Matrix

Matrix hỗ trợ một số loại thao tác: thiết lập (set), pre-nhân (pre), post-nhân (post), nối (concat), nghịch đảo (invert) và ánh xạ (map). Mỗi loại phục vụ mục đích riêng khi xây dựng các biến đổi phức tạp.

Các thao tác Pre và Post

preTranslate nhân ma trận hiện tại ở bên trái với ma trận di chuyển: result = translate × current. postTranslate nhân ở bên phải: result = current × translate. Sự khác biệt nằm ở thứ tự áp dụng: các thao tác pre được áp dụng trước các biến đổi hiện tại, các thao tác post được áp dụng sau. Điều tương tự áp dụng cho preScale, postScale, preRotate, postRotate và preSkew, postSkew.

Nghịch đảo và nối

invert(Matrix inverse) tính toán ma trận nghịch đảo. Nếu ma trận gốc là suy biến (định thức bằng không), nó trả về false. concat(Matrix other) nhân ma trận hiện tại với ma trận được cung cấp: set = set × other. Để có thứ tự ngược lại, hãy sử dụng setConcat(other, this).

Map — áp dụng cho các điểm và hình chữ nhật

mapRect(RectF rect) biến đổi một hình chữ nhật và trả về kết quả trong một RectF mới. mapPoints(float[] dst, float[] src) biến đổi một mảng các điểm. mapVectors(float[] dst, float[] src) biến đổi các vectơ — mà không tính đến di chuyển. mapRect hữu ích để tính toán hộp bao sau khi biến đổi.

Ứng dụng trong Canvas và Bitmap

Matrix được sử dụng tích cực trong hai tình huống đồ họa Android chính: biến đổi Canvas và biến đổi Bitmap. Trong cả hai trường hợp, Matrix xác định cách đầu ra đồ họa sẽ được sửa đổi.

Biến đổi Canvas qua Matrix

Canvas cung cấp canvas.setMatrix(matrix) để thay thế hoàn toàn ma trận hiện tại và canvas.concat(matrix) để nhân biến đổi hiện tại với ma trận được cung cấp. Sau khi áp dụng Matrix, tất cả việc vẽ tiếp theo — các lệnh gọi drawBitmap, drawRect, drawPath — được thực hiện trong hệ tọa độ đã biến đổi. Canvas cũng duy trì ngăn xếp trạng thái đã lưu của riêng mình thông qua save()restore().

Biến đổi Bitmap qua Matrix

Bitmap.createBitmap(Bitmap source, int x, int y, int width, int height, Matrix matrix, boolean filter) tạo một Bitmap mới với biến đổi được cung cấp áp dụng. Đây là một công cụ mạnh mẽ để tạo các bản sao hình ảnh được thay đổi kích thước, xoay hoặc biến dạng mà không làm mất Bitmap gốc. Tham số filter kiểm soát khử răng cưa trong quá trình nội suy pixel.

setPolyToPoly — các phép biến đổi phối cảnh

setPolyToPoly(float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount) — một khả năng độc đáo của Matrix không có tương đương trực tiếp trong CGAffineTransform. Nó tính toán một ma trận biến đổi các điểm cho trước từ một đa giác này sang một đa giác khác. Với pointCount = 4, một phép biến đổi phối cảnh (chiếu) hoàn chỉnh được tạo ra, cho phép lớp phủ Bitmap với biến dạng phối cảnh.

Ví dụ mã Kotlin

Hãy xem các ví dụ thực tế về việc sử dụng Matrix để biến đổi đồ họa trong ứng dụng Android với Kotlin.

Các phép biến đổi affine cơ bản

Ví dụ tạo một Matrix cho một biến đổi kết hợp: di chuyển (100, 50), thay đổi kích thước 1.5x và xoay 45 độ. Việc sử dụng postTranslate sau preRotate và preScale sẽ thay đổi thứ tự áp dụng các thao tác.

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

// Áp dụng cho các điểm
val pts = floatArrayOf(0f, 0f, 100f, 100f)
matrix.mapPoints(pts)

// Áp dụng cho hình chữ nhật
val rect = RectF(0f, 0f, 200f, 100f)
matrix.mapRect(rect)

Biến đổi Canvas với save và restore

Ví dụ minh họa việc áp dụng Matrix vào Canvas trong onDraw để xoay và thay đổi kích thước một hình tròn quanh tâm của nó. Lưu và khôi phục trạng thái Canvas đảm bảo rằng biến đổi không ảnh hưởng đến các phần tử vẽ tiếp theo.

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()
}

Biến dạng phối cảnh qua setPolyToPoly

Ví dụ sử dụng setPolyToPoly để tạo biến dạng phối cảnh của một Bitmap. Bốn điểm nguồn (các góc của hình chữ nhật ban đầu) được ánh xạ tới bốn điểm đích tạo thành một hình thang. Kết quả là hiệu ứng hình ảnh nghiêng trong không gian.

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
    )
}

Câu hỏi thường gặp

Matrix khác Camera trong Android như thế nào?

Matrix làm việc với các phép biến đổi affine và phối cảnh hai chiều thông qua một ma trận 3×3 duy nhất. Camera (android.graphics.Camera) là một lớp cấp cao hơn mô phỏng máy ảnh ba chiều: nó tạo vòng quay 3D và sau đó chiếu kết quả vào Matrix 2D. Camera sử dụng Matrix bên trong.

Làm thế nào để xoay Bitmap 90 độ?

Tạo một Matrix với postRotate(90f) và truyền nó vào Bitmap.createBitmap(original, 0, 0, w, h, matrix, true). Lưu ý rằng khi xoay 90 độ, chiều rộng và chiều cao của kết quả sẽ đổi chỗ cho nhau. Khi xoay một góc tùy ý, có thể cần cắt xén để tránh các vùng trống.

Làm thế nào để lấy phép biến đổi nghịch đảo của Matrix?

Sử dụng matrix.invert(resultMatrix). Phương thức trả về true nếu việc nghịch đảo thành công và ghi ma trận nghịch đảo vào resultMatrix. Việc nghịch đảo có thể không thực hiện được nếu ma trận suy biến (ví dụ, khi tỷ lệ bằng không). Luôn kiểm tra giá trị trả về.

Sự khác biệt giữa các thao tác pre và post là gì?

pre nhân biến đổi mới với bên trái: result = operation × current — thao tác được áp dụng trước các biến đổi hiện tại. post nhân ở bên phải: result = current × operation — thao tác được áp dụng sau. Đối với chuỗi preRotate + postTranslate: đầu tiên xoay, sau đó di chuyển.

Có thể sử dụng Matrix trong Compose không?

, Matrix được sử dụng trong Jetpack Compose thông qua lớp android.graphics.Matrix trong tương tác với Canvas Compose. Trong Compose, graphicsLayer có sẵn cho các biến đổi (scale, rotationX, translationX và các biến khác), nhưng đối với các biến đổi Bitmap phức tạp, Matrix được sử dụng trong mã drawWithContent hoặc drawBehind.

Tổng kết

  • Matrix — lớp Android cho các phép biến đổi affine và phối cảnh với ma trận 3×3
  • Bốn loại cơ bản: translate, scale, rotate, skew
  • Các thao tác pre/post kiểm soát thứ tự áp dụng: pre — trước các biến đổi hiện tại, post — sau các biến đổi hiện tại
  • setPolyToPoly — hàm duy nhất để tính toán phép biến đổi phối cảnh từ 4 cặp điểm
  • Matrix được áp dụng cho Canvas qua concat, cho Bitmap qua createBitmap với Matrix, cho các điểm qua mapPoints
  • invert tính toán phép biến đổi nghịch đảo, trả về false cho các ma trận suy biến
  • isAffineisIdentity giúp phân loại trạng thái ma trận để tối ưu hóa

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm