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
}
}
Вы видите что-нибудь, что может вызвать проблему? Это меня ошеломляет.