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