如何通过CameraX调用长焦镜头实现变焦,无需适配厂商专属API
使用CameraX调用多镜头(长焦/广角)实现变焦的实现方案
CameraX从1.1.0版本开始原生支持多物理镜头筛选,无需接入厂商专属API,通过Camera2基础属性即可实现长焦、广角镜头的调用,具体实现步骤如下:
前置依赖配置
首先确保项目引入的CameraX版本≥1.1.0,示例Gradle依赖:
dependencies { def camerax_version = "1.3.0" implementation "androidx.camera:camera-core:$camerax_version" implementation "androidx.camera:camera-camera2:$camerax_version" implementation "androidx.camera:camera-lifecycle:$camerax_version" }
核心实现步骤
- 第一步:筛选区分不同类型的后置镜头
通过CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS参数获取镜头焦距,数值越小对应广角镜头,数值越大对应长焦镜头,中间值为主摄:
val cameraProvider = ProcessCameraProvider.getInstance(context).get() // 筛选所有后置摄像头 val backCameras = cameraProvider.availableCameraInfos.filter { it.lensFacing == CameraSelector.LENS_FACING_BACK } // 按焦距区分镜头类型 val lensFocalMap = mutableMapOf<String, Float>() backCameras.forEach { cameraInfo -> val camera2Info = cameraInfo as Camera2CameraInfo val focalLengths = camera2Info.getCameraCharacteristic(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS) focalLengths?.firstOrNull()?.let { focal -> lensFocalMap[camera2Info.cameraId] = focal } } // 排序得到不同镜头 val sortedLenses = lensFocalMap.toList().sortedBy { it.second } val wideAngleLens = backCameras.find { (it as Camera2CameraInfo).cameraId == sortedLenses.firstOrNull()?.first } val telephotoLens = backCameras.find { (it as Camera2CameraInfo).cameraId == sortedLenses.lastOrNull()?.first } val mainLens = backCameras.find { (it as Camera2CameraInfo).cameraId == sortedLenses.getOrNull(sortedLenses.size/2)?.first }
- 第二步:绑定指定镜头到拍摄用例
需要切换长焦/广角时,构造对应镜头的CameraSelector,重新绑定Preview、ImageCapture等用例即可:
// 示例:绑定长焦镜头 val telephotoSelector = telephotoLens?.let { CameraSelector.Builder().addCameraFilter { listOf(it) }.build() } telephotoSelector?.let { selector -> cameraProvider.unbindAll() val camera = cameraProvider.bindToLifecycle( lifecycleOwner, selector, preview, imageCapture ) }
- 第三步:结合镜头自身的变焦能力调整参数
每个镜头绑定后,可通过CameraControl调用变焦接口,在当前镜头的支持范围内调整变焦比,多镜头配合即可覆盖远超单主摄的变焦范围:
// 获取当前镜头支持的最大变焦比 val maxZoom = camera.cameraInfo.zoomState.value?.maxZoomRatio ?: 1f // 设置指定变焦比 camera.cameraControl.setZoomRatio(2f)
注意事项
- Manifest中需要申请
android.hardware.camera.any权限,不要仅申请android.hardware.camera,避免部分设备无法识别多镜头 - 切换镜头前必须调用
unbindAll()解绑之前的用例,避免出现硬件冲突 - 如果需要实现用户滑动变焦条的无缝切换效果,可以提前获取所有镜头的变焦范围,计算切换阈值,到达临界值时自动切换对应镜头再调整变焦比即可
内容的提问来源于stack exchange,提问作者LCZ
相关产品推荐
相关产品推荐

