Camera
Camera2
基础概念
CameraManager
相机的系统服务,可以用来获得一些初步的信息和动作比如:
打开相机
使用一个状态回调和一个线程handler来打开相机,继而走向stateCallback回调进行下一步操作
1 | manager.openCamera(cameraId, stateCallback, mBackgroundHandler); |
获得相机列表
一个设备存在前后置摄像头,以及外置摄像头,CameraManager
可以获得摄像头ID列表
1 | manager.getCameraIdList(); |
获得具体摄像头的描述信息
1 | manager.getCameraCharacteristics(cameraId); |
CameraDevice
相机设备的抽象集合,但是和Camera的API不太相同,包含的功能并没有那么多。
- 关闭相机
- 创键Capture会话
- 创键Capture请求
Camera2中,许多的操作都被抽象的定义为了Capture请求
比如预览连续重复的Capture请求,拍照则是一次Capture,甚至聚焦、闪关灯、等各种操作也都作为Capture的参数来进行请求。当然录象也是
所以大致我们流程是:
- 获取CameraManager
- 去开启指定ID的摄像头
- 配置图像数据载体,即摄像头的数据由谁接受
- 创建Capture会话
- 配置Capture请求
- 发送请求
准备工作
检查权限
首先我们使用相机肯定是要声明相机等权限和声明功能
1 | <uses-permission android:name="android.permission.CAMERA"/> |
接着就是动态检查或请求权限了。
准备Handler
相机的诸多操作为了不给主线程麻烦,当然是需要在子线程中运行的。所以创建线程,获得到Handler
。
1 | mBackgroundThread = new HandlerThread("CameraBackground"); |
准备预览载体Surface
这里我们通过创建TextureView来获得Surface
打开相机
这里我们首先通过获得到CameraManager
,通过CameraManager
去获取具体摄像头的描述信息,通过这些描述信息我们可以拿到Sensor的方向,以及Sensor支持的尺寸集,然后根据需要进行配置。继而进行打开相机。
1 |
预览
预览本质上是将实时的帧图像不断重复的显示并且覆盖在载体上。
拍照
录像
其它操作
坑
相机sensor的自然方向和屏幕自然方向
通常描述一张图片分辨率是这样width * height,比如720 * 1080的图片。
屏幕自然自然方向,也就是人手持竖直方向的。以左上角为基准参照点展开内容。如果横屏之类的话,同样内容展开还是以左上角为内容参照点向下向右展开。
但是相机sensor方向却一直是固定的。和手机向右横屏的左上角是同一参照点。那么问题来了。竖直情况下拍摄一张图片,比如我们所看到理解的是一张720x1080的图片,但是实际上在相机sensor来说是一张1080x702。照片还是那张照片,造成了输出照片就是横着的。所以这种情况下就需要进行顺时针旋转,旋转完成后,图片才会从1080x720,变为720x1080,这是时候就可以按照正常方向显示了。
YUV进行旋转后同样,YUV里面的数据只是连续不断的字节流,需要我们给他加上分辨率,才能正确的解释为一张图片。也就是需要按照分辨率进行解析。就好比如你给了宽和高,它就能被抽象化为一个二维的字节数组,然后分别对应着像素点的。所以在我们将YUV数据进行显示或者输入到编码器时需要给与正确显示分辨率,编码器才能够正确的进行编码。