CameraX 曝光补偿 API 入门指南
背景
在摄影中,曝光是决定最终相机所呈现图像的最重要因素之一,因此大多数摄影师都极力将曝光调至最佳。自动曝光 (AE) 模式在大多数常见拍摄场景下的效果都不错,比如自动快速拍照。然而在某些特定条件下,AE 模式会为了照片的整体质量而做出一些妥协,而这些妥协有时并不是您想要的。其中一个例子就是逆光,例如,在室内朝向窗户或者其它光源的位置拍摄,或者在室外拍摄,拍摄对象的后方刚好是太阳。在这些拍摄场景中,AE 模式会因为明亮的背景 (照片中高亮的区域) 而对照片进行适当曝光,但是处于黑暗前景中的主体就会变得过于昏暗或者成为剪影效果。图 1 展示的是在相同条件 (室内逆光) 下使用不同曝光进行拍摄的三张照片。
AE 对于照片的整体质量控制得很好,但是更高的曝光确实能够捕获到 Android 公仔的更多画面细节。
光圈: 镜片的打开程度,它控制相机的进光量
快门速度: 照片曝光的持续时间
ISO (国际标准化组织): 相机感光元件对捕获光线的敏感程度
实现曝光补偿 API
曝光补偿 API 根据生成的自动曝光值,通过曝光补偿指数调整曝光补偿度。曝光补偿指数可以为正值 (用于提高照片亮度) 或者负值 (降低照片亮度)。它将整体曝光范围映射到补偿指数的取值区间,并将曝光总量映射到 EV 步长。相机设备内部会根据曝光指数改变曝光,减少控制其它参数的操作并且达到同一效果。
以图 1 为例,相机的默认配置无法为我们希望对焦的主体提供足够的亮度,所以我们可以使用正值指数的曝光补偿配置来获得两倍或者四倍的曝光,从而突出主体。通过改变曝光补偿指数,相机内部会控制快门速度、光圈和 ISO 以获得合适的曝光。
要获得补偿指数,CameraX 实现了以下内容:
CameraControl::setExposureCompensationIndex,用于设置新的曝光补偿指数。 https://developer.android.google.cn/reference/kotlin/androidx/camera/core/CameraControl#setexposurecompensationindex ExposureState 用于曝光补偿性能和当前配置,包括: https://developer.android.google.cn/reference/kotlin/androidx/camera/core/ExposureState 支持调整补偿 所支持的补偿范围 所支持的补偿步长 当前补偿指数值
使用曝光补偿 API
查询曝光补偿范围 设置新的曝光补偿指数 当 CameraX 确认后继续后续操作
查询曝光补偿指数的范围
曝光补偿值的范围依赖相机设备的配置和硬件级别;应用可以通过 ExposureState 接口查询所支持的取值范围:
val camera = cameraProvider.bindToLifecycle( … )
val range = camera.cameraInfo.exposureState.exposureCompensationRange
设置新的曝光补偿指数
interface CameraControl {
fun setExposureCompensationIndex(value: Int): ListenableFuture<Int!>
}
var exposureIndex = 0
val camera = cameraProvider.bindToLifecycle(
lifecycleOwner,
getCameraSelector(),
preview,
imageCapture,
)
evButton.setOnClickListener {
val range = camera.cameraInfo.exposureState.exposureCompensationRange
if (range.contains(exposureIndex + 1)) {
camera.cameraControl.setExposureCompensationIndex(++exposureIndex)
val ev = camera.cameraInfo.exposureState.exposureCompensationStep.toFloat() * exposureIndex
Log.i("CameraXLog", "EV: $ev")
}
}
绑定用例
https://developer.android.google.cn/training/camerax/architecture#combine-use-casesListenableFuture<Int>
https://developer.android.google.cn/reference/androidx/camera/core/CameraControl#setExposureCompensationIndex(int)
关联补偿指数和曝光值 (EV)
val camera = cameraProvider.bindToLifecycle( … )
val exposureValue = camera.cameraInfo.exposureState.exposureCompensationStep.toFloat() * exposureIndex
例如: exposure_compensation_index 等于 6,compensation_step 等于 ⅓,那么曝光补偿计算为 +2 EV,也就是两倍的默认曝光值。
compensation_step 的 step_size 取值通常为 ⅓ 或者 ½,较少情况下,有些设备可能会支持 1 或者甚至 ¼。所能支持的最大曝光值一般是 2 EV 或者 3 EV。
CameraX 曝光补偿 API 的可用性
https://developer.android.google.cn/jetpack/androidx/releases/camera
总结
GitHub
https://github.com/wenhungwww/android-camerax-ev-sample官方文档
https://developer.android.google.cn/training/cameraxCameraX 讨论组
https://groups.google.com/a/android.com/g/camerax-developersCameraX issues
https://issuetracker.google.com/issues/new?component=618491&template=1257717
相关阅读
setExposureCompensationIndex API
https://developer.android.google.cn/reference/androidx/camera/core/CameraControl#setExposureCompensationIndex(int) ExposureState API
https://developer.android.google.cn/reference/androidx/camera/core/ExposureStateCameraX 版本说明 https://developer.android.google.cn/jetpack/androidx/releases/camera Codelab: 上手使用 CameraX https://developer.android.google.cn/codelabs/camerax-getting-started GitHub 示例
https://github.com/android/camera-samples
推荐阅读