خروجی مورد استفاده CameraX دوگانه است: میانگیر و اطلاعات تبدیل. میانگیر آرایهای از بایتها است و اطلاعات تبدیل نحوه برش و چرخش میانگیر قبلاز نمایش به کاربران نهایی است. نحوه اعمال تبدیل به قالب میانگیر بستگی دارد.
ImageCapture
برای مورد استفاده 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 }
جاوا
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; }