Android Composable - неправильная ширина / высота в PreviewView

В настоящее время используется Composable для создания PreviewView для CameraX. Однако, как вы можете видеть на изображении, реальный вид отображается некорректно и требует многократного переключения камеры, чтобы оно стало правильным. Почему это? Я приложил свой исходный код для справки.

Неправильная ширина и высота

      class CameraPreview {
private var cameraProvider: ProcessCameraProvider? = null
private var lensFacing: Int = CameraSelector.LENS_FACING_BACK
private var camera: Camera? = null
private lateinit var displayManager: DisplayManager
private var preview: Preview? = null


@RequiresApi(Build.VERSION_CODES.R)
@Composable
fun DisplayCamera() {
    val context = LocalContext.current
    val lifecycleOwner = LocalLifecycleOwner.current
    val cameraProviderFuture = remember { ProcessCameraProvider.getInstance(context) }
    displayManager = context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
    lateinit var previewView: PreviewView
    var executor: Executor
    Scaffold(topBar = { },
        floatingActionButton = {
            FloatingActionButton(
                onClick = {
                    lensFacing = if (CameraSelector.LENS_FACING_FRONT == lensFacing) {
                        CameraSelector.LENS_FACING_BACK
                    } else {
                        CameraSelector.LENS_FACING_FRONT
                    }
                    bindCameraUseCases(previewView, lifecycleOwner, context)
                },
                modifier = Modifier.padding(20.dp)
            ) {
                Icon(Icons.Default.SwitchCamera,"")
            }
        }, content = {
            AndroidView(modifier = Modifier.fillMaxSize(),
                factory = { _context ->
                previewView = PreviewView(_context)
                executor = ContextCompat.getMainExecutor(_context)
                cameraProviderFuture.addListener({
                    cameraProvider = cameraProviderFuture.get()
                    lensFacing = when {
                        hasBackCamera() -> CameraSelector.LENS_FACING_BACK
                        hasFrontCamera() -> CameraSelector.LENS_FACING_FRONT
                        else -> throw IllegalStateException("Back and front camera are unavailable")
                    }

                    bindCameraUseCases(previewView, lifecycleOwner, context)

                }, ContextCompat.getMainExecutor(context))
                previewView
            })
        }
    )
}

@RequiresApi(Build.VERSION_CODES.R)
private fun bindCameraUseCases(previewView: PreviewView, lifecycleOwner: LifecycleOwner, context: Context) {

    val metrics: DisplayMetrics = context.getResources().getDisplayMetrics()
    val screenAspectRatio = aspectRatio(metrics.widthPixels, metrics.heightPixels)
    val rotation = displayManager.displays[0].rotation
    val cameraProvider = cameraProvider
        ?: throw IllegalStateException("Camera initialization failed.")
    val cameraSelector = CameraSelector.Builder().requireLensFacing(lensFacing).build()
    preview = Preview.Builder()
        .setTargetAspectRatio(screenAspectRatio)
        .setTargetRotation(rotation)
        .build()
    cameraProvider.unbindAll()
    try {
        camera = cameraProvider.bindToLifecycle(
            lifecycleOwner, cameraSelector, preview)
        preview?.setSurfaceProvider(previewView.surfaceProvider)
    } catch (exc: Exception) {
        Log.e("PEOPLE DETECTOR", "Use case binding failed", exc)
    }
}

private fun aspectRatio(width: Int, height: Int): Int {
    val previewRatio = max(width, height).toDouble() / min(width, height)
    if (abs(previewRatio - RATIO_4_3_VALUE) <= abs(previewRatio - RATIO_16_9_VALUE)) {
        return AspectRatio.RATIO_4_3
    }
    return AspectRatio.RATIO_16_9
}

private fun hasBackCamera(): Boolean {
    return cameraProvider?.hasCamera(CameraSelector.DEFAULT_BACK_CAMERA) ?: false
}

private fun hasFrontCamera(): Boolean {
    return cameraProvider?.hasCamera(CameraSelector.DEFAULT_FRONT_CAMERA) ?: false
}

companion object {
    private const val RATIO_4_3_VALUE = 4.0 / 3.0
    private const val RATIO_16_9_VALUE = 16.0 / 9.0
}

}

Вы видите что-нибудь, что может вызвать проблему? Это меня ошеломляет.

0 ответов

Другие вопросы по тегам