เอาต์พุตของ Use Case ของ CameraX มี 2 อย่าง ได้แก่ บัฟเฟอร์และข้อมูลการเปลี่ยนรูปแบบ บัฟเฟอร์คืออาร์เรย์ไบต์ และข้อมูลการเปลี่ยนรูปแบบคือวิธีครอบตัดและพลิกบัฟเฟอร์ก่อนที่จะแสดงต่อผู้ใช้ปลายทาง วิธีใช้การเปลี่ยนรูปแบบจะขึ้นอยู่กับรูปแบบของบัฟเฟอร์
จับภาพ
สำหรับ Use Case ของ ImageCapture
จะมีการใช้บัฟเฟอร์สี่เหลี่ยมครอบตัดก่อนบันทึกลงในดิสก์และระบบจะบันทึกการหมุนไว้ในข้อมูล Exif แอปไม่จำเป็นต้องดำเนินการใดๆ เพิ่มเติม
แสดงตัวอย่าง
สำหรับ Use Case ของ Preview
คุณจะรับข้อมูลการเปลี่ยนรูปแบบได้โดยเรียกใช้
SurfaceRequest.setTransformationInfoListener()
ทุกครั้งที่มีการอัปเดตการเปลี่ยนรูปแบบ ผู้โทรจะได้รับออบเจ็กต์ SurfaceRequest.TransformationInfo
ใหม่
วิธีใช้ข้อมูลการเปลี่ยนรูปแบบจะขึ้นอยู่กับแหล่งที่มาของ Surface
และมักจะซับซ้อน หากเป้าหมายคือการแสดงตัวอย่างเท่านั้น ให้ใช้ PreviewView
PreviewView
คือมุมมองที่กําหนดเองซึ่งจัดการการเปลี่ยนรูปแบบโดยอัตโนมัติ สำหรับการใช้งานขั้นสูง เมื่อคุณต้องแก้ไขสตรีมตัวอย่าง เช่น ด้วย OpenGL ให้ดูตัวอย่างโค้ดในแอปทดสอบหลัก CameraX
แปลงพิกัด
งานทั่วไปอีกอย่างหนึ่งคือการใช้พิกัดแทนบัฟเฟอร์ เช่น การวาดกล่องรอบใบหน้าที่ตรวจพบในตัวอย่าง ในกรณีเช่นนี้ คุณต้องเปลี่ยนพิกัดของใบหน้าที่ตรวจพบจากการวิเคราะห์รูปภาพเป็นตัวอย่าง
ข้อมูลโค้ดต่อไปนี้สร้างเมทริกซ์ที่จับคู่จากพิกัดการวิเคราะห์รูปภาพกับพิกัด PreviewView
หากต้องการแปลงพิกัด (x, y)
ด้วย Matrix
โปรดดู
Matrix.mapPoints()
Kotlin
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 }
Java
Matrix getMappingMatrix(ImageProxy imageProxy, PreviewView previewView) { Rect cropRect = imageProxy.getCropRect(); int rotationDegrees = imageProxy.getImageInfo().getRotationDegrees(); Matrix matrix = new Matrix(); // A float array of the source vertices (crop rect) in clockwise order. float[] source = { cropRect.left, cropRect.top, cropRect.right, cropRect.top, cropRect.right, cropRect.bottom, cropRect.left, cropRect.bottom }; // A float array of the destination vertices in clockwise order. float[] destination = { 0f, 0f, previewView.getWidth(), 0f, previewView.getWidth(), previewView.getHeight(), 0f, previewView.getHeight() }; // 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. int vertexSize = 2; // The destination needs to be shifted 1 vertex for every 90° rotation. int shiftOffset = rotationDegrees / 90 * vertexSize; float[] tempArray = destination.clone(); for (int toIndex = 0; toIndex < source.length; toIndex++) { int fromIndex = (toIndex + shiftOffset) % source.length; destination[toIndex] = tempArray[fromIndex]; } matrix.setPolyToPoly(source, 0, destination, 0, 4); return matrix; }