xin*_*aiz 8 android kotlin android-camera2 android-camerax
我尝试使用CameraX api为我的应用内相机实现广角选项,但遇到了一个问题 -CameraControl.setZoomRatio允许在ZoomState.getMinZoomRatio()和之间设置变焦ZoomState.getMaxZoomRatio(),在我测试的手机上minZoomRatio是1.0f。同一款手机支持缩小到0.5f系统相机内。
当前片段我如何初始化相机:
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)
)
}
Run Code Online (Sandbox Code Playgroud)
当前捏合缩放实现:
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
}
Run Code Online (Sandbox Code Playgroud)
我的问题是可以使用CameraX api 使用广角相机(或实现0.5f变焦),还是必须使用Camera2重写整个实现。
正如问题下面的评论中所解释的,广角镜头相机(以及任何其他相机,例如,如果我们尝试实现变焦 x20,则为大变焦)是单独的相机,因此为了允许在普通相机和(例如)广角镜头相机之间切换,我们必须使用不同的相机选择器重新启动相机视图。我们如何重新启动它,这取决于我们(例如,在某些捏合后重新启动或通过切换相机的按钮重新启动)。
这是相机选择器,根据startCameraData.ultraWide参数获取后置摄像头或广角镜头后置摄像头:
val cameraSelector = if (startCameraData.ultraWide) {
CameraSelector.Builder()
.addCameraFilter { cameraInfos ->
// filter back cameras with minimum sensor pixel size
val backCameras = cameraInfos.filterIsInstance<Camera2CameraInfoImpl>()
.filter {
val pixelWidth = it.cameraCharacteristicsCompat.get(CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE)?.width ?: 0
it.lensFacing == CameraSelector.LENS_FACING_BACK && pixelWidth >= 2000 // arbitrary number resolved empirically
}
// try to find wide lens camera, if not present, default to general backCameras
backCameras.minByOrNull {
val focalLengths = it.cameraCharacteristicsCompat.get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS)
focalLengths?.getOrNull(0) ?: 0f
}
?.let { listOf(it) } ?: backCameras
}
.build()
} else {
CameraSelector.DEFAULT_BACK_CAMERA
}
Run Code Online (Sandbox Code Playgroud)
注意:
Camera2 api 可能无法让我们访问某些摄像头,具体取决于手机,但有时也会,除非应用程序包被 Google 列入白名单。例如,“打开相机”应用程序 ( net.sourceforge.opencamera) 已列入白名单,并且可以访问所有相机。我通过将应用程序包更改为进行了测试net.sourceforge.opencamera,突然得到了 6 个相机 ID,而不是 3 个。
| 归档时间: |
|
| 查看次数: |
2805 次 |
| 最近记录: |