Android Camera2 学习(一)

从 Android 5.0 开始,Google 引入了一套全新的相机框架 Camera2(android.hardware.camera2)并且废弃了旧的相机框架 Camera1(android.hardware.Camera)。

一、关于 Camera2

1. Camera2 的API模型

Camera2 的 API 模型被设计成一个 Pipeline(管道),它按顺序处理每一帧的请求并返回请求结果给客户端

Pipeline示意图

根据 Pipeline 的示意图,假设我们想要开启闪光灯并同时拍摄两张不同尺寸的图片,则整个拍摄流程如下:

  1. 创建一个用于从 Pipeline 获取图片的 CaptureRequest
  2. 修改 CaptureRequest 的设置,开启闪光灯
  3. 创建两个不同尺寸的 Surface 用于接收图片数据,并添加到 CaptureRequest 中
  4. 发送配置好的 CaptureRequest 到 Pipeline 中,等待返回拍照结果
  • 一个新的 CaptureRequest 会被放入一个被称作 Pending Request Queue 的队列中等待被执行;
  • 当 In-Flight Capture Queue 队列空闲的时候就会从 Pending Request Queue 获取若干个待处理的 CaptureRequest,并且根据每一个 CaptureRequest 的配置进行 Capture 操作
  • 最后从不同尺寸的 Surface 中获取图片数据,并得到一个包含了很多与本次拍照相关的信息的 CaptureResult,流程结束。

2. 一些概念

2.1 Supported Hardware Level

相机功能的强大与否和硬件息息相关,不同厂商对 Camera2 的支持程度也不同。Camera2 使用 Supported Hardware Level 这一概念来区分不同设备对于 Camera2 的支持情况。截止到 Android P 为止,从低到高一共有 LEGACY、LIMITED、FULL 和 LEVEL_3 四个级别:

  • LEGACY:向后兼容的级别,处于该级别的设备意味着它只支持 Camera1 的功能,不具备任何 Camera2 高级特性。
  • LIMITED:除了支持 Camera1 的基础功能之外,还支持部分 Camera2 高级特性的级别。
  • FULL:支持所有 Camera2 的高级特性。
  • LEVEL_3:新增更多 Camera2 高级特性,例如 YUV 数据 的后处理等。

2.2 CameraManager

CameraManager 是一个负责查询和建立相机连接的系统服务,它的主要功能包括:

  • 根据指定的相机 ID 连接相机设备。
  • 将相机信息封装到 CameraCharacteristics 中,并设置获取 CameraCharacteristics 实例的方式。

2.3 CameraCharacteristics

CameraCharacteristics 中封装了大量的相机信息。比如:

  • LENS_FACING:相机的朝向信息
  • FLASH_INFO_AVAILABLE:相机的闪光灯是否可用
  • CONTROL_AE_AVAILABLE_MODES :相机的所有可用 AE 模式等等。

2.4 CameraDevice

CameraDevice 代表当前连接的相机设备,它的职责有以下四个:

  • 根据指定的参数创建 CameraCaptureSession。
  • 根据指定的模板创建 CaptureRequest。
  • 关闭相机设备。
  • 监听相机设备的状态,例如断开连接、开启成功和开启失败等。

Camera2 中的 CameraDevice 与 Camera1 中 Camera类 的区别:

  • Camera1 中的 Camera 类 几乎负责了所有相机的操作;
  • CameraDevice 的功能比较单一,只负责建立相机连接的事务,关于更为细化的相机操作则由 CameraCaptureSession 完成

2.5 CameraCaptureSession

CameraCaptureSession 实际上就是配置了目标 Surface 的 Pipeline 实例

我们在使用相机功能之前必须先创建 CameraCaptureSession 实例。一个 CameraDevice 一次只能开启一个 CameraCaptureSession,绝大部分的相机操作都是通过向 CameraCaptureSession 提交一个 Capture 请求实现的,例如拍照、连拍、设置闪光灯模式、触摸对焦、显示预览画面等等。

2.6 Surface

Surface 是一块用于填充图像数据的内存空间。例如你可以使用 SurfaceView 的 Surface 接收每一帧预览数据用于显示预览画面,也可以使用 ImageReader 的 Surface 接收 JPEG 或 YUV 数据。

每一个 Surface 都可以有自己的尺寸和数据格式,你可以从 CameraCharacteristics 获取某一个数据格式支持的尺寸列表

2.7 CaptureRequest

CaptureRequest 是向 CameraCaptureSession 提交 Capture 请求时的信息载体,其内部包括了本次 Capture 的参数配置和接收图像数据的 Surface。

CaptureRequest 可以配置的信息非常多,包括图像格式、图像分辨率、传感器控制、闪光灯控制、3A 控制等等,可以说绝大部分的相机参数都是通过 CaptureRequest 配置的。值得注意的是每一个 CaptureRequest 表示一帧画面的操作,这意味着你可以精确控制每一帧的 Capture 操作。

2.8 Capture

相机的所有操作和参数配置最终都是用于图像捕获。因此,在 Camera2 中将关于相机的所有操作和参数配置抽象为 Capture

Capture 从执行方式上又被细分为【单次模式】、【多次模式】和【重复模式】:

  • 单次模式(One-shot):即只执行一次的 Capture 操作,如设置闪光灯模式、设置对焦模式,进行单次拍照等等。多个单次模式的 Capture 会进入队列按顺序执行。
  • 多次模式(Burst): 即连续多次执行指定的 Capture 操作。注意与多次执行单次模式的区别,多次模式下的连续多次的 Capture 操作 期间不允许插入其他任何 Capture 操作。例如连续拍摄 100 张照片,在拍摄这 100 张照片期间任何新的 Capture 请求都会排队等待,直到拍完 100 张照片。多组多次模式的 Capture 会进入队列按顺序执行。
  • 重复模式(Reapeating):即不断重复执行指定的 Capture 操作,当有其他模式的 Capture 提交时会暂停该模式,转而执行其他被模式的 Capture,当其他模式的 Capture 执行完毕后又会自动恢复继续执行该模式的 Capture。例如显示预览画面就是不断 Capture 获取每一帧画面。该模式的 Capture 是全局唯一的,也就是新提交的重复模式 Capture 会覆盖旧的重复模式 Capture。

2.9 CaptureResult

CaptureResult 是每一次 Capture 操作的结果,里面包括了很多状态信息,包括闪光灯状态、对焦状态、时间戳等等。例如你可以在拍照完成的时候,通过 CaptureResult 获取本次拍照时的对焦状态和时间戳。

需要注意的是,CaptureResult 并不包含任何图像数据,前面我们在介绍 Surface 的时候说了,图像数据都是从 Surface 获取的。

二、Camera2 的新特性

  • 可以在相机开启之前通过 CameraCharacteristics 得到相机信息并检查
  • 可以在不开启预览的情况下拍照
  • 可以在一次拍摄中得到多张不同格式和尺寸的图片
  • 可以控制曝光时间
  • 可以进行连拍
  • 可以灵活地进行3A控制(AF,AE,AWB)

三、tips

  • Camera2 的 API 调用也会很耗时,所以对于所有的相机操作,建议使用独立的线程进行。避免在主线程中调用 Camera2 的 API,HandlerThread 是一个不错的选择
  • 与 Camera1 的严格区分不同, Camera2 将预览和拍照都抽象成了 Capture 行为,只不过一个是不断重复的 Capture,一个是一次性的 Capture 而已。
  • Camera2 所有的相机操作都可以注册相关的回调接口,然后在不同的回调方法里写业务逻辑,这可能会让你的代码因为不够线性而错综复杂,建议你可以尝试使用子线程的阻塞方式来尽可能地保证代码的线性执行(熟悉 Dart 的人一定很喜欢它的 async 和 await 操作)。例如在子线程阻塞等待 CaptureResult,然后继续执行后续的操作,而不是将代码拆分到到 CaptureCallback.onCaptureCompleted() 方法里。
  • 当设备的 Supported Hardware Level 低于 FULL 的时候,建议还是使用 Camera1,因为 FULL 级别以下的 Camera2 能提供的功能几乎和 Camera1 一样,所以倒不如选择更加稳定的 Camera1。

相关参考:
Android Camera2 教程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值