本篇主要就几个关键的类进行解释,并且对需要注意的点注释,此外再总结一下如何使用Camera2进行拍照和预览的流程。附上官方demo。
上面是Camera2的流程示意图,由于我喜欢从整体思路上分析代码,所以下面先就整个呆萌的思路拓展一下。
首先肯定是解决相机的问题啦,毕竟是主角嘛,但是相机是底层的,Android为我们抽象了CameraDevice
类,用来表示各个相机。我们又知道,设备的相机通常有好几个,前后的特点都不一样,比如镜像问题,单单一个CameraDevice
无法表示全。这时候可能有人会想把CameraDevice
做成抽象类,每个相机作为子类各自配置自己的属性,反正打开相机的操作不依赖相机本身,只需要相机的标识就行,打开相机以后再将该相机的实例对象返回给调用者就ok了,没错,呆萌也是这样想的:
@Override
public void onOpened(@NonNull CameraDevice cameraDevice) {
mCameraDevice = cameraDevice;
}
相机设备的问题解决了,但是谁来拍照啊,打开相机不可能让CameraDevice
自己打开自己吧,所以需要一个CameraManager
来管理相机的开启,相机是系统级别的,所以返回的Manager
都是一样的也无妨,就将其上升到服务的层次,只要有上下文就能获取,通过下面的方法获取并进行拍照。
CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
manager.openCamera(mCameraId, mStateCallback, mBackgroundHandler);
呆萌又想,如果都交给CameraManager
来管理,它还是要管理好多东西哦,比如相机的取景方向,这是个大问题,见解析(1),为了满足单一职责原则和开闭原则,不如将相机设备的属性封装成一个类,这样CameraDevice
只需要专注于创建对话Session
就行了, 于是CameraCharacteristics
应运而生,其封装了指定ID的相机中的各种属性,例如想要获取指定ID相机的取景方向:
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
mSensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
我们知道,相机设备是嵌入在Android设备当中的,两者之间的通信需要底层的知识,但是我们不需要知道,所以Android为我们提供了CameraCaptureSession
这个上层类,翻译为相机捕捉的对话,显然这个对话为我们预览和拍摄做了封装,其作用相当于图中的pipeline
。
打开相机后就可以通过管道进行配置了,而相机的各种配置很多,用户的需求也是不一样的,如果在对话管道CameraCapt