I tried to implement wide angle option for my in-app camera using CameraX api but ran into an issue - CameraControl.setZoomRatio
allows to set zoom between ZoomState.getMinZoomRatio()
and ZoomState.getMaxZoomRatio()
, where on phones I tested it minZoomRatio
is 1.0f
. The same phone supports zoom down to 0.5f
in system camera.
Current snippets how I initialize the camera:
private var camera: Camera? = null
private var imageCapture: ImageCapture? = null
private fun startCamera() {
val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
cameraProviderFuture.addListener({
val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
val preview = Preview.Builder()
.build()
.also {
it.setSurfaceProvider(binding.viewFinder.surfaceProvider)
}
imageCapture = ImageCapture.Builder()
.setFlashMode(ImageCapture.FLASH_MODE_AUTO)
.build()
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
try {
cameraProvider.unbindAll()
camera = cameraProvider.bindToLifecycle(
this, cameraSelector, preview, imageCapture
)
viewModel.onCameraStarted()
} catch (exc: Exception) {
Timber.e(exc)
}
},
ContextCompat.getMainExecutor(this)
)
}
Current pinch to zoom implementation:
val scaleGestureDetector = ScaleGestureDetector(this,
object : ScaleGestureDetector.SimpleOnScaleGestureListener() {
override fun onScale(detector: ScaleGestureDetector): Boolean {
val camera = camera ?: return false
val zoomState = camera.cameraInfo.zoomState.value ?: return false
val scale = zoomState.zoomRatio * detector.scaleFactor
val finalScale =
scale.coerceIn(MIN_ZOOM, MAX_ZOOM).coerceIn(zoomState.minZoomRatio, zoomState.maxZoomRatio)
camera.cameraControl.setZoomRatio(finalScale)
return true
}
})
binding.viewFinder.setOnTouchListener { view, event ->
view.performClick()
scaleGestureDetector.onTouchEvent(event)
return@setOnTouchListener true
}
My question is it possible to use wide angle camera (or achieve 0.5f
zoom) using CameraX api, or do I have to rewrite whole implementation using Camera2.