برونداد تبدیل

خروجی یک مورد استفاده 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
}