เปลี่ยนรูปแบบเอาต์พุต

เอาต์พุตของ Use Case ของ CameraX มี 2 ส่วน ได้แก่ บัฟเฟอร์และข้อมูลการเปลี่ยนรูปแบบ บัฟเฟอร์คืออาร์เรย์ไบต์ และข้อมูลการเปลี่ยนรูปแบบคือวิธีครอบตัดและหมุนบัฟเฟอร์ก่อนที่จะแสดงต่อผู้ใช้ปลายทาง วิธีใช้การเปลี่ยนรูปแบบจะขึ้นอยู่กับรูปแบบของบัฟเฟอร์

ImageCapture

สำหรับ Use Case ImageCapture ระบบจะใช้บัฟเฟอร์สี่เหลี่ยมผืนผ้าครอบตัดก่อนบันทึกลงในดิสก์ และระบบจะบันทึกการหมุนไว้ในข้อมูล Exif แอปไม่จำเป็นต้องดำเนินการใดๆ เพิ่มเติม

แสดงตัวอย่าง

สําหรับกรณีการใช้งาน Preview คุณสามารถดูข้อมูลการเปลี่ยนรูปแบบได้โดยเรียกใช้ SurfaceRequest.setTransformationInfoListener() ทุกครั้งที่มีการอัปเดตการเปลี่ยนรูปแบบ ผู้เรียกจะได้รับออบเจ็กต์ SurfaceRequest.TransformationInfo ใหม่

วิธีใช้ข้อมูลการเปลี่ยนรูปแบบจะขึ้นอยู่กับแหล่งที่มาของ Surface และมักจะมีความซับซ้อน หากเป้าหมายคือการแสดงตัวอย่างเท่านั้น ให้ใช้ PreviewView PreviewView เป็นมุมมองที่กำหนดเองซึ่งจะจัดการการเปลี่ยนรูปแบบโดยอัตโนมัติ สำหรับการใช้งานขั้นสูง เมื่อคุณต้องการแก้ไขสตรีมตัวอย่าง เช่น ด้วย OpenGL ให้ดูตัวอย่างโค้ดในแอปทดสอบหลักของ CameraX

แปลงพิกัด

งานทั่วไปอีกอย่างหนึ่งคือการทำงานกับพิกัดแทนบัฟเฟอร์ เช่น การวาดกล่องรอบใบหน้าที่ตรวจพบในตัวอย่าง ในกรณีเช่นนี้ คุณต้องเปลี่ยนรูปแบบพิกัดของใบหน้าที่ตรวจพบจากการวิเคราะห์รูปภาพเป็นตัวอย่าง

ข้อมูลโค้ดต่อไปนี้จะสร้างเมทริกซ์ที่แมปจากพิกัดการวิเคราะห์รูปภาพไปยังพิกัด PreviewView หากต้องการเปลี่ยนรูปแบบพิกัด (x, y) ด้วย Matrix โปรดดู Matrix.mapPoints()

fun getCorrectionMatrix(imageProxy: ImageProxy, previewView: PreviewView): Matrix {
    val cropRect = imageProxy.cropRect
    val rotationDegrees = imageProxy.imageInfo.rotationDegrees
    val matrix = Matrix()

    // A float array of the source vertices (crop rect) in clockwise order.
    val source = floatArrayOf(
        cropRect.left.toFloat(),
        cropRect.top.toFloat(),
        cropRect.right.toFloat(),
        cropRect.top.toFloat(),
        cropRect.right.toFloat(),
        cropRect.bottom.toFloat(),
        cropRect.left.toFloat(),
        cropRect.bottom.toFloat()
    )

    // A float array of the destination vertices in clockwise order.
    val destination = floatArrayOf(
        0f,
        0f,
        previewView.width.toFloat(),
        0f,
        previewView.width.toFloat(),
        previewView.height.toFloat(),
        0f,
        previewView.height.toFloat()
    )

    // The destination vertexes need to be shifted based on rotation degrees. The
    // rotation degree represents the clockwise rotation needed to correct the image.

    // Each vertex is represented by 2 float numbers in the vertices array.
    val vertexSize = 2
    // The destination needs to be shifted 1 vertex for every 90° rotation.
    val shiftOffset = rotationDegrees / 90 * vertexSize
    val tempArray = destination.clone()
    for (toIndex in source.indices) {
        val fromIndex = (toIndex + shiftOffset) % source.size
        destination[toIndex] = tempArray[fromIndex]
    }
    matrix.setPolyToPoly(source, 0, destination, 0, 4)
    return matrix
}