Matrix ใน Android: ความหมาย ประเภทของเมทริกซ์ และการทำงานกับการแปลง

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-07-22 เวลาอ่าน: 9 นาที

Matrix — คือคลาสจาก Android SDK (android.graphics.Matrix) ที่แสดงถึงการแปลงแบบ affine ผ่านเมทริกซ์ 3×3 ใช้สำหรับการแปลงวัตถุกราฟิก — การเคลื่อนที่ การปรับขนาด การหมุน และการเอียง ตามเอกสาร Android Developers Documentation (2026) Matrix เป็นเครื่องมือหลักสำหรับการทำงานกับการแปลงใน Canvas, Bitmap และ Drawable โดยให้การควบคุมพิกัดที่แม่นยำในการวาดแบบกำหนดเอง

สาระสำคัญ

  • Matrix — คลาส Android สำหรับการแปลงแบบ affine และ perspective ด้วยเมทริกซ์ 3×3
  • การดำเนินการแบบ Affine: translate (เลื่อน), scale (ปรับขนาด), rotate (หมุน) และ skew (เอียง)
  • Matrix รองรับการแปลงแบบ perspective (projective) ผ่าน setPolyToPoly
  • ลำดับการดำเนินการมีความสำคัญ — Matrix.concat ทำการคูณตามลำดับ
  • Matrix ถูกนำไปใช้กับ Canvas, Bitmap, RectF, PointF และ Path ในงานกราฟิก Android

Matrix ใน Android คืออะไร?

Matrix (android.graphics.Matrix) — คือคลาส Android SDK ที่แสดงถึงเมทริกซ์ทางคณิตศาสตร์ขนาด 3×3 ใช้สำหรับการแปลงพิกัดสองมิติ Matrix เป็นองค์ประกอบพื้นฐานสำหรับการแปลงกราฟิกทั้งหมดใน Android — ตั้งแต่การเลื่อนและปรับขนาด Canvas ไปจนถึงการบิดเบือน Perspective ที่ซับซ้อนของ Bitmap

แตกต่างจาก iOS ที่ใช้โครงสร้างแยก CGAffineTransform (affine) และ CATransform3D (3D) Android รวมการแปลงแบบ affine และ perspective ไว้ในคลาสเดียวคือ Matrix เมทริกซ์ 3×3 ช่วยให้สามารถแสดงทั้งการดำเนินการ affine มาตรฐาน (แถวสุดท้าย [0, 0, 1]) และการบิดเบือนแบบ perspective เมื่อแถวสุดท้ายมีค่าใด ๆ ซึ่งให้ความยืดหยุ่นมากกว่า แต่ต้องเข้าใจคณิตศาสตร์ของเมทริกซ์

Matrix ทำงานร่วมกับ Canvas API อย่างใกล้ชิด เมื่อนักพัฒนาเรียก canvas.translate(), canvas.scale() หรือ canvas.rotate() เมธอดเหล่านี้จะปรับเปลี่ยนเมทริกซ์ของบริบทกราฟิกภายใน สามารถรับเมทริกซ์ปัจจุบันของ Canvas ได้ผ่าน canvas.getMatrix() และนำเมทริกซ์ที่กำหนดเองไปใช้ด้วยตนเองผ่าน canvas.setMatrix() หรือ canvas.concat()

ประเภทของการแปลงด้วย Matrix

Matrix รองรับการแปลงแบบ affine พื้นฐานสี่ประเภท: 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 ที่มุมบวกหมายถึงทวนเข็มนาฬิกา) หากไม่ได้ระบุ px, py การหมุนจะทำรอบจุดกำเนิด

Skew — การเอียง

Skew (เฉือน) ทำให้วัตถุผิดรูป โดยเอียงตามแกน X (kx) หรือแกน Y (ky) ค่า 1.0 จะเอียง 45 องศา Skew ใช้สำหรับสร้างเอฟเฟกต์การเอียง เลียนแบบลักษณะสามมิติ (pseudo-3D) และการบิดเบือนเปอร์สเปคทีฟ

โครงสร้างของเมทริกซ์ 3×3

Matrix จัดเก็บองค์ประกอบของเมทริกซ์ 3×3 ในอาเรย์ภายในขนาด 9 ค่าทศนิยม (float[9]) ลำดับการจัดเก็บเป็นแบบ column-major (ตามคอลัมน์) ซึ่งสอดคล้องกับการแสดงทางคณิตศาสตร์มาตรฐาน การเข้าถึงแต่ละองค์ประกอบทำผ่านค่าคงที่: Matrix.MSCALE_X, Matrix.MSKEW_Y, Matrix.MTRANS_X และอื่น ๆ

องค์ประกอบของเมทริกซ์

เมทริกซ์ ถูกจัดเรียงดังนี้: สองคอลัมน์แรก (MSCALE_X, MSKEW_X, MSKEW_Y, MSCALE_Y) รับผิดชอบการปรับขนาด การหมุน และการเอียง คอลัมน์ที่สาม (MTRANS_X, MTRANS_Y, MPERSP_2) — สำหรับการเลื่อนและเปอร์สเปคทีฟ สำหรับการแปลงแบบ affine MPERSP_0 และ MPERSP_1 มีค่าเท่ากับ 0 และ MPERSP_2 มีค่าเท่ากับ 1

การรับค่าเมทริกซ์ใช้ getValues(float[] values) ซึ่งเติมอาเรย์ขนาด 9 องค์ประกอบ สำหรับการตั้งค่าใช้ setValues(float[] values) ซึ่งช่วยให้จัดการเมทริกซ์ได้โดยตรงสำหรับการแปลงที่ซับซ้อนซึ่งเกินขอบเขตของเมธอดมาตรฐาน translate, scale, rotate และ skew

การตรวจสอบประเภทของเมทริกซ์

Matrix มีเมธอดหลายตัวสำหรับการจำแนกสถานะปัจจุบัน isIdentity() ตรวจสอบว่าเมทริกซ์เป็นเมทริกซ์เอกลักษณ์หรือไม่ isAffine() — ตรวจสอบว่ามีเฉพาะการแปลงแบบ affine หรือไม่ (MPERSP_0 = 0, MPERSP_1 = 0, MPERSP_2 = 1) การตรวจสอบเหล่านี้มีประโยชน์สำหรับการปรับให้เหมาะสม: หากเมทริกซ์เป็นเมทริกซ์เอกลักษณ์ สามารถข้ามการแปลงได้

การดำเนินการหลักกับ Matrix

Matrix รองรับการดำเนินการหลายประเภท: การตั้งค่า (set) การคูณหน้า (pre) การคูณหลัง (post) การต่อกัน (concat) การผกผัน (invert) และการแมป (map) แต่ละประเภทมีหน้าที่ของตัวเองในการสร้างการแปลงที่ซับซ้อน

การดำเนินการ Pre และ Post

preTranslate คูณเมทริกซ์ปัจจุบันทางซ้ายด้วยเมทริกซ์การเลื่อน: result = translate × current postTranslate คูณทางขวา: 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 มีประโยชน์สำหรับการคำนวณ bounding box หลังการแปลง

การประยุกต์ใช้ใน Canvas และ Bitmap

Matrix ถูกใช้อย่างแพร่หลายในสองสถานการณ์หลักของกราฟิก Android: การแปลง Canvas และการแปลง Bitmap ในทั้งสองกรณี Matrix จะกำหนดว่าผลลัพธ์กราฟิกจะถูกเปลี่ยนแปลงอย่างไร

การแปลง Canvas ผ่าน Matrix

Canvas มีเมธอด canvas.setMatrix(matrix) สำหรับการแทนที่เมทริกซ์ปัจจุบันทั้งหมด และ canvas.concat(matrix) สำหรับการคูณการแปลงปัจจุบันด้วยเมทริกซ์ที่ส่งเข้า หลังจากใช้ Matrix การวาดทั้งหมดที่ตามมา — การเรียก drawBitmap, drawRect, drawPath — จะดำเนินการในระบบพิกัดที่ถูกแปลงแล้ว Canvas ยังมีสแต็กสถานะที่บันทึกไว้ของตัวเองผ่าน save() และ restore()

การแปลง Bitmap ผ่าน Matrix

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

มาดู ตัวอย่างเชิงปฏิบัติ ของการใช้ Matrix สำหรับการแปลงกราฟิกในแอปพลิเคชัน Android ด้วย Kotlin

การแปลงแบบ Affine พื้นฐาน

ตัวอย่างสร้าง Matrix สำหรับการแปลงแบบรวม: เลื่อนไปที่ (100, 50) ปรับขนาด 1.5 เท่า และหมุน 45 องศา การใช้ postTranslate หลังจาก preRotate และ preScale จะเปลี่ยนลำดับของการดำเนินการ

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)

การแปลง Canvas ด้วย save และ restore

ตัวอย่างสาธิต การใช้ Matrix กับ Canvas ใน onDraw สำหรับการหมุนและปรับขนาดวงกลมรอบจุดศูนย์กลาง การบันทึกและเรียกคืนสถานะ 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
    )
}

คำถามที่พบบ่อย

Matrix แตกต่างจาก Camera ใน Android อย่างไร?

Matrix ทำงานกับการแปลงสองมิติแบบ affine และ perspective ผ่านเมทริกซ์ 3×3 หนึ่งตัว Camera (android.graphics.Camera) — เป็นคลาสระดับสูงกว่าที่จำลองกล้องสามมิติ: มันสร้างการหมุน 3D แล้วฉายผลลัพธ์ลงใน 2D Matrix Camera ใช้ Matrix ภายใน

จะหมุน Bitmap 90 องศาได้อย่างไร?

สร้าง Matrix ด้วย postRotate(90f) และส่งต่อไปยัง 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: หมุนก่อน แล้วค่อยเลื่อน

สามารถใช้ Matrix ใน Compose ได้หรือไม่?

ได้ Matrix ใช้ใน Jetpack Compose ผ่านคลาส android.graphics.Matrix ในการทำงานร่วมกับ Canvas ของ Compose ใน Compose มี graphicsLayer สำหรับการแปลง (scale, rotationX, translationX และอื่น ๆ) แต่สำหรับการแปลง Bitmap ที่ซับซ้อน จะใช้ Matrix ในโค้ด drawWithContent หรือ drawBehind

สรุป

  • Matrix — คลาส Android สำหรับการแปลงแบบ affine และ perspective ด้วยเมทริกซ์ 3×3
  • สี่ประเภทพื้นฐาน: translate (เลื่อน), scale (ปรับขนาด), rotate (หมุน), skew (เอียง)
  • การดำเนินการ pre/post ควบคุมลำดับการใช้งาน: pre — ก่อนการแปลงปัจจุบัน, post — หลังการแปลงปัจจุบัน
  • setPolyToPoly — ฟังก์ชันเฉพาะสำหรับคำนวณการแปลงแบบเปอร์สเปคทีฟจากจุด 4 คู่
  • Matrix ถูกนำไปใช้กับ Canvas ผ่าน concat, กับ Bitmap ผ่าน createBitmap ด้วย Matrix, กับจุดผ่าน mapPoints
  • invert คำนวณการแปลงผกผัน คืนค่า false สำหรับเมทริกซ์เอกฐาน
  • isAffine และ isIdentity ช่วยจำแนกสถานะของเมทริกซ์เพื่อการปรับให้เหมาะสม

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม