如何使用Android CameraX设置对焦区域的宽度和高度?
安卓CameraX自定义对焦/测光区域尺寸实现方案
方案1:CameraX原生API实现(无需Camera2互操作)
你提到的size参数对应归一化缩放系数的计算逻辑是正确的,按照需求实现50dp见方的测光矩形只需要把目标尺寸转换为对应归一化系数即可,不同CameraX版本的实现稍有区别:
- CameraX 核心版本 ≥ 1.2.0:官方已提供单独设置宽高的API,可实现精准控制
步骤如下:- 先将50dp转换为像素值
val targetDp = 50f val targetPx = TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, targetDp, resources.displayMetrics )- 基于PreviewView的尺寸计算归一化宽高系数
val previewWidth = previewView.width.toFloat() val previewHeight = previewView.height.toFloat() // 归一化宽高 = 目标尺寸px / 预览View对应边尺寸 val normWidth = targetPx / previewWidth val normHeight = targetPx / previewHeight- 构建自定义尺寸的MeteringPoint并触发对焦
// centerX、centerY为你之前设置的对焦点坐标(PreviewView坐标系) val meteringPoint = MeteringPoint.Builder(centerX, centerY) .setWidth(normWidth) .setHeight(normHeight) .build() // 触发对焦测光 val focusAction = FocusMeteringAction.Builder(meteringPoint) .setAutoCancelDuration(3, TimeUnit.SECONDS) .build() camera.cameraControl.startFocusAndMetering(focusAction) - CameraX 核心版本 < 1.2.0:无单独宽高设置接口,可使用统一
size参数做近似实现,绝大多数场景下误差可接受// 取宽高归一化系数的平均值作为size值 val normSize = (targetPx / previewWidth + targetPx / previewHeight) / 2f val meteringPoint = previewView.meteringPointFactory.createPoint(centerX, centerY, normSize) // 后续对焦触发逻辑和上文一致
方案2:Camera2互操作实现(完全自定义需求)
如果需要更底层的精准控制,可借助CameraX的Camera2互操作接口实现:
- 先从CameraCharacteristics中获取传感器有效区域
SENSOR_INFO_ACTIVE_ARRAY_SIZE,以及当前预览的裁剪区域 - 将50dp对应的预览区域转换为传感器坐标系下的矩形
- 通过Camera2Interop将区域参数配置到捕获请求中
// 构造Camera2互操作配置 val camera2Config = Camera2Config.Builder() .setCaptureRequestOption(CaptureRequest.CONTROL_AF_REGIONS, arrayOf(calculatedSensorRect)) .setCaptureRequestOption(CaptureRequest.CONTROL_AE_REGIONS, arrayOf(calculatedSensorRect)) .setCaptureRequestOption(CaptureRequest.CONTROL_AWB_REGIONS, arrayOf(calculatedSensorRect)) .build() // 绑定CameraX用例时传入该配置即可
注意事项
- 计算尺寸时需注意坐标系对齐,不要混淆PreviewView的视图坐标系和传感器的硬件坐标系
- 对焦/测光区域大小不能超过传感器有效区域,超出范围的数值会被系统自动裁剪
内容的提问来源于stack exchange,提问作者Howie S. Nguyen
相关产品推荐
相关产品推荐

