Android Camera2 之 CaptureRequest 和 CaptureResult
CaptureRequest 介绍一、简介CaptureRequest 表示一个捕捉的请求。我们可以为不同的场景(预览、拍照)创建不同的捕捉请求,并可以配置不同的捕捉属性,如:预览分辨率,预览目标,对焦模式、曝光模式等等。官方文档链接:https://developer.android.com/reference/android/hardware/camera2/CaptureRequest...
CaptureRequest 介绍
一、简介
CaptureRequest
表示一个捕捉的请求。我们可以为不同的场景(预览、拍照)创建不同的捕捉请求,并可以配置不同的捕捉属性,如:预览分辨率,预览目标,对焦模式、曝光模式等等。
官方文档链接:https://developer.android.com/reference/android/hardware/camera2/CaptureRequest
二、获取 CaptureRequest 实例
通过 CameraDevice
对象的 createCaptureRequest()
方法得到一个 CaptureRequest.Builder
对象,基本配置都是通过该构造者来配置;最后通过 CaptureRequest.Builder
对象的 build()
方法便可得到 CaptureRequest
实例。
示例(以拍照的捕捉请求为例):
private void captureStillPicture() {
try {
final Activity activity = getActivity();
if (null == activity || null == mCameraDevice) {
return;
}
// 1. 先拿到一个 CaptureRequest.Builder 对象
final CaptureRequest.Builder captureBuilder =
mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
captureBuilder.addTarget(mImageReader.getSurface());
// 2. 通过 CaptureRequest.Builder 对象设置一些捕捉请求的配置
captureBuilder.set(CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
setAutoFlash(captureBuilder);
int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, getOrientation(rotation));
CameraCaptureSession.CaptureCallback CaptureCallback
= new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session,
@NonNull CaptureRequest request,
@NonNull TotalCaptureResult result) {
// start preview
}
};
mCaptureSession.stopRepeating();
mCaptureSession.abortCaptures();
// 3. 通过 CaptureRequest.Builder 对象的 `build()` 方法构建一个 CaptureRequest 对象
mCaptureSession.capture(captureBuilder.build(), CaptureCallback, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
重点关注上面3个中文注释的地方即可。
三、内部类
1. CaptureRequest.Builder
典型的建造者模式,是 CaptureRequest 的构建者。
获取:
使用 CameraDevice.createCaptureRequest(int)
方法获取一个 CaptureRequest.Builder 对象。其中的 int 取值为:
- TEMPLATE_PREVIEW : 用于创建一个相机预览请求。相机会优先保证高帧率而不是高画质。适用于所有相机设备。
- TEMPLATE_STILL_CAPTURE : 用于创建一个拍照请求。相机会优先保证高画质而不是高帧率。适用于所有相机设备。
- TEMPLATE_RECORD : 用于创建一个录像请求。相机会使用标准帧率,并设置录像级别的画质。适用于所有相机设备。
- TEMPLATE_VIDEO_SNAPSHOT : 用于创建一个录像时拍照的请求。相机会尽可能的保证照片质量的同时不破坏正在录制的视频质量。适用于硬件支持级别高于
LEGACY
的相机设备。 - TEMPLATE_ZERO_SHUTTER_LAG : 用于创建一个零延迟拍照的请求。相机会尽可能的保证照片质量的同时不损失预览图像的帧率,3A(自动曝光、自动聚焦、自动白平衡)都为 auto 模式。只适用于支持
PRIVATE_REPROCESSING
和YUV_REPROCESSING
的相机设备。 - TEMPLATE_MANUAL : 用于创建一个手动控制相机参数的请求。相机所有自动控制将被禁用,后期处理参数为预览质量,手动控制参数被设置为合适的默认值,需要用户自己根据需求来调整各参数。适用于支持
MANUAL_SENSOR
的相机设备。
常用方法:
方法 | 描述 |
---|---|
void addTarget(Surface outputTarget) | 添加一个请求的输出surface,注意这个surface必须包含在 CameraDevice.createCaptureSession() 方法设置的输出surface集合中 |
CaptureRequest build() | 使用当前配置构建一个CaptureRequest对象 |
T get(Key key) | 获取指定key的值 |
void removeTarget(Surface outputTarget) | 移除指定的输出surface |
void set(Key key, T value) | 设置指定key的值 |
void setTag(Object tag) | 为该请求设置一个标签 |
2. CaptureRequest.Key
上面 get/set
方法中的 Key 类就是这个内部类了,用作 CaptureRequest.Builder 的属性字段设置和查询使用。
注意:
之前介绍 CameraCharacteristics 时有提到一个方法是 getAvailableCaptureRequestKeys()
就是得到该相机设备可用的 CaptureRequest.Key 列表。
四、方法
重写的 Parcelable
接口和 Object 类的一些方法就不介绍了,以下是几个可能用得着的方法。
1. T get(Key key)
和 CaptureRequest.Builder 中的 get 方法效果是一样的。
2. List<Key<?>> getKeys()
返回映射中包含的所有 Key 的列表。
3. Object getTag()
检索此请求的标签,如果有的话。对应 CaptureRequest.Builder 中的 setTag() 方法。
4. boolean isReprocess()
判断这是否是一个再处理的请求。
五、成员字段
这些字段就是用于 CaptureRequest.Builder 的 set() 方法的。
挺多的,而且大多涉及到一些相机的相关术语,我懂的也不多,大部分还是靠翻译。不清晰的地方建议还是看官方文档吧。
类型 | 字段名 | 描述 |
---|---|---|
public static final Key<Boolean> | BLACK_LEVEL_LOCK | 黑电平补偿是锁定在当前值上,还是自由变化。当设置为true (ON)时,在将锁设置为false (OFF)之前,用于黑电平补偿的值不会更改 |
public static final Key<Integer> | COLOR_CORRECTION_ABERRATION_MODE | 色差校正算法的操作模式 |
public static final Key<RggbChannelVector> | COLOR_CORRECTION_GAINS | 颜色校正增益 |
public static final Key<Integer> | COLOR_CORRECTION_MODE | 颜色校正模式,应用于将传感器原始颜色转换为线性的 sRGB 颜色 |
public static final Key<ColorSpaceTransform> | COLOR_CORRECTION_TRANSFORM | 一个将传感器 RGB 颜色空间转换到线性的 sRGB 颜色空间的转换矩阵 |
public static final Key<Integer> | CONTROL_AE_ANTIBANDING_MODE | 相机自动曝光算法的反冲带补偿所需的设置 |
public static final Key<Integer> | CONTROL_AE_EXPOSURE_COMPENSATION | 调整自动曝光(AE)目标图像亮度 |
public static final Key<Boolean> | CONTROL_AE_LOCK | 自动曝光(AE)现在是否锁定为其最新计算值 |
public static final Key<Integer> | CONTROL_AE_MODE | 相机自动曝光程序所需的模式 |
public static final Key<Integer> | CONTROL_AE_PRECAPTURE_TRIGGER | 相机设备在处理此请求时是否触发预捕获测光 |
public static final Key<MeteringRectangle[]> | CONTROL_AE_REGIONS | 用于自动曝光的测光区域列表 |
public static final Key<Range<Integer>> | CONTROL_AE_TARGET_FPS_RANGE | 自动曝光程序保持良好捕捉帧率的曝光范围 |
public static final Key<Integer> | CONTROL_AF_MODE | 自动对焦(AF)当前是否启用,以及设置为何种模式 |
public static final Key<MeteringRectangle[]> | CONTROL_AF_REGIONS | 用于自动聚焦的测光区域列表 |
public static final Key<Integer> | CONTROL_AF_TRIGGER | 相机设备是否会为该请求触发自动对焦 |
public static final Key<Boolean> | CONTROL_AWB_LOCK | 自动白平衡(AWB)现在是否锁定为其最新计算值 |
public static final Key<Integer> | CONTROL_AWB_MODE | 自动白平衡(AWB)当前是否设置颜色转换字段,以及它的光照目标是什么 |
public static final Key<MeteringRectangle[]> | CONTROL_AWB_REGIONS | 用于自动白平衡光源估计的测光区域列表 |
public static final Key<Integer> | CONTROL_CAPTURE_INTENT | 关于该捕捉目的的3A(自动曝光,自动对焦,自动白平衡)信息,帮助相机设备决定最优的3A策略 |
public static final Key<Integer> | CONTROL_EFFECT_MODE | 应用一个特殊的颜色影响 |
public static final Key<Boolean> | CONTROL_ENABLE_ZSL | 运行相机设备为 android.control.captureIntent == STILL_CAPTURE 的请求开启零延迟(zero-shutter-lag)模式 |
public static final Key<Integer> | CONTROL_MODE | 整个3A控制程序模式 |
public static final Key<Integer> | CONTROL_POST_RAW_SENSITIVITY_BOOST | 捕获原始传感器数据后应用于输出图像的额外灵敏度提升量 |
public static final Key<Integer> | CONTROL_SCENE_MODE | 当前处于活动状态的场景模式 |
public static final Key<Integer> | CONTROL_VIDEO_STABILIZATION_MODE | 视频稳定是否激活 |
public static final Creator<CaptureRequest> | CREATOR | 实现的 Parcelable 接口所需的静态对象 |
public static final Key<Integer> | DISTORTION_CORRECTION_MODE | 镜头畸变校正块的操作模式 |
public static final Key<Integer> | EDGE_MODE | 边缘增强的操作模式 |
public static final Key<Integer> | FLASH_MODE | 相机设备闪光控制所需的模式 |
public static final Key<Integer> | HOT_PIXEL_MODE | 热像素校正的操作模式 |
public static final Key<Location> | JPEG_GPS_LOCATION | 生成图像GPS元数据时使用的位置对象 |
public static final Key<Integer> | JPEG_ORIENTATION | JPEG图像的方向 |
public static final Key<Byte> | JPEG_QUALITY | JPEG图像的压缩质量 |
public static final Key<Byte> | JPEG_THUMBNAIL_QUALITY | JPEG缩略图的压缩质量 |
public static final Key<Size> | JPEG_THUMBNAIL_SIZE | JPEG缩略图的分辨率大小 |
public static final Key<Float> | LENS_APERTURE | 所需的透镜孔径大小,作为透镜焦距与有效孔径的比值 |
public static final Key<Float> | LENS_FILTER_DENSITY | 镜头中性密度滤镜所需的设置 |
public static final Key<Float> | LENS_FOCAL_LENGTH | 所需镜头焦距,用于光学变焦 |
public static final Key<Float> | LENS_FOCUS_DISTANCE | 从镜头最前面的表面到最清晰焦点平面的期望距离 |
public static final Key<Integer> | LENS_OPTICAL_STABILIZATION_MODE | 设置拍照设备在拍照时是否使用光学稳像(OIS) |
public static final Key<Integer> | NOISE_REDUCTION_MODE | 降噪算法的操作模式 |
public static final Key<Float> | REPROCESS_EFFECTIVE_EXPOSURE_FACTOR | 在发送再处理之前,应用程序处理应用于原始输出帧的曝光时间增加因子的数量 |
public static final Key<Rect> | SCALER_CROP_REGION | 传感器读取此捕获所需的区域 |
public static final Key<Long> | SENSOR_EXPOSURE_TIME | 每个像素曝光的持续时间 |
public static final Key<Long> | SENSOR_FRAME_DURATION | 从某一帧曝光开始到下一帧曝光开始的持续时间 |
public static final Key<Integer> | SENSOR_SENSITIVITY | 处理前应用于传感器数据的增益量 |
public static final Key<int[]> | SENSOR_TEST_PATTERN_DATA | 一个像素[R, G_even, G_odd, B]提供给测试模式,当 android.sensor.testPatternMode 是 SOLID_COLOR 时 |
public static final Key<Integer> | SENSOR_TEST_PATTERN_MODE | 当启用时,传感器发送一个测试模式,而不是从相机进行真正的曝光 |
public static final Key<Integer> | SHADING_MODE | 用于图像数据的镜头阴影校正质量 |
public static final Key<Integer> | STATISTICS_FACE_DETECT_MODE | 人脸检测单元的操作模式 |
public static final Key<Boolean> | STATISTICS_HOT_PIXEL_MAP_MODE | 热像素映射表生成的操作模式 |
public static final Key<Integer> | STATISTICS_LENS_SHADING_MAP_MODE | 摄像机设备是否将镜头阴影映射输出到输出结果元数据中 |
public static final Key<Integer> | STATISTICS_OIS_DATA_MODE | 一种用于选择输出结果元数据中是否包含光学稳定(OIS)位置信息的控制 |
public static final Key<TonemapCurve> | TONEMAP_CURVE | 调色/对比度/伽马曲线的使用,当 android.tonemap.mode 是 CONTRAST_CURVE 时 |
public static final Key<Float> | TONEMAP_GAMMA | 当 android.tonemap.mode 是 GAMMA_VALUE 时。tonemap 曲线定义如下公式:* OUT = pow(IN, 1.0 / gamma),其中IN和OUT为按比例缩放到范围[0.0,1.0]的输入像素值,pow为幂函数,gamma为该键指定的gamma值 |
public static final Key<Integer> | TONEMAP_MODE | 高级全局对比度/伽马/调理控制 |
public static final Key<Integer> | TONEMAP_PRESET_CURVE | 当 android.tonemap.mode 是 PRESET_CURVE 时,tonemap曲线将由指定的标准定义。 |
CaptureResult 介绍
一、简介
CaptureResult
表示捕捉的结果,是从图像传感器捕获单个图像的结果的子集。包含捕获硬件(传感器、镜头、闪光灯)、处理管道、控制算法和输出缓冲区的最终配置的子集。
捕获结果由摄像机在对捕获请求进行处理后产生。还可以对捕获结果查询为捕获请求列出的所有属性,以确定捕获使用的最终值。结果还包括捕获过程中相机设备状态的附加元数据。
CaptureResult 对象也是不可变的。常使用的子类是 TotalCaptureResult
。
官方文档链接:https://developer.android.com/reference/android/hardware/camera2/CaptureResult
二、获取
我们在 CameraCaptureSession.CaptureCallback 类的回调方法 onCaptureProgressed()
和 onCaptureCompleted()
中都可以拿到 CaptureResult 的对象。
关于 CameraCaptureSession.CaptureCallback 回调的介绍,可以参考:https://blog.csdn.net/afei__/article/details/86108482
示例:
/**
* A {@link CameraCaptureSession.CaptureCallback} that handles events related to JPEG capture.
*/
private CameraCaptureSession.CaptureCallback mCaptureCallback
= new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureProgressed(@NonNull CameraCaptureSession session,
@NonNull CaptureRequest request,
@NonNull CaptureResult partialResult) {
process(partialResult);
}
@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session,
@NonNull CaptureRequest request,
@NonNull TotalCaptureResult result) {
process(result);
}
private void process(CaptureResult result) {
switch (mState) {
case STATE_PREVIEW: {
// We have nothing to do when the camera preview is working normally.
break;
}
case STATE_WAITING_LOCK: {
Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
if (afState == null) {
captureStillPicture();
} else if (CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED == afState ||
CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED == afState) {
// CONTROL_AE_STATE can be null on some devices
Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
if (aeState == null ||
aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) {
mState = STATE_PICTURE_TAKEN;
captureStillPicture();
} else {
runPrecaptureSequence();
}
}
break;
}
case STATE_WAITING_PRECAPTURE: {
// CONTROL_AE_STATE can be null on some devices
Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
if (aeState == null ||
aeState == CaptureResult.CONTROL_AE_STATE_PRECAPTURE ||
aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED) {
mState = STATE_WAITING_NON_PRECAPTURE;
}
break;
}
case STATE_WAITING_NON_PRECAPTURE: {
// CONTROL_AE_STATE can be null on some devices
Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
if (aeState == null || aeState != CaptureResult.CONTROL_AE_STATE_PRECAPTURE) {
mState = STATE_PICTURE_TAKEN;
captureStillPicture();
}
break;
}
}
}
};
三、内部类
只有一个 CaptureResult.Key<T>
的内部类,用于 CaptureResult 类的字段查找。
类比于 CameraCharacteristics.Key
和 CaptureRequest.Key
。
四、常用方法
1. T get(Key key)
获取 CaptureResult 中指定 key 的值,key 为 CaptureResult 类中的那些静态常量。
2. long getFrameNumber()
获取该结果申请的帧的数量。
3. List<Key<?>> getKeys()
返回映射中包含的所有 Key 的列表。
4. CaptureRequest getRequest()
返回这个结果对应的 CaptureRequest 对象。
5. int getSequenceId()
获取发生故障时的序列ID。
五、成员字段
同 CaptureRequest
差不多。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)