Android Camera2 之 CameraDevice 详解
一、简介
CameraDevice
是一个连接的相机设备代表,你可以把它看作为相机设备在 java 代码中的表现。类比于旧 API 中的 Camera
类。
官方文档链接:https://developer.android.google.cn/reference/android/hardware/camera2/CameraDevice
二、获取 CameraDevice 实例
通过 CameraManager
的 openCamera()
方法打开相机,在 CameraDevice.StateCallback
的 onOpened(CameraDevice camera)
方法中可获得 CameraDevice 的实例。
示例:
private int mCameraId = CameraCharacteristics.LENS_FACING_FRONT; private CameraManager mCameraManager; // 相机管理者 private CameraDevice mCameraDevice; // 相机对象 private Handler mBackgroundHandler; private HandlerThread mBackgroundThread; private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() { @Override public void onOpened(@NonNull CameraDevice camera) { mCameraDevice = camera; // 获取到可用的 CameraDevice 实例 // 当相机成功打开时回调该方法,接下来可以执行创建预览的操作 } @Override public void onDisconnected(@NonNull CameraDevice camera) { // 当相机断开连接时回调该方法,应该在此执行释放相机的操作 } @Override public void onError(@NonNull CameraDevice camera, int error) { // 当相机打开失败时,应该在此执行释放相机的操作 } @Override public void onClosed(@NonNull CameraDevice camera) { // 当相机关闭时回调该方法,这个方法可以不用实现 } }; public void openCamera() { try { // 前处理 mCameraManager.openCamera(Integer.toString(mCameraId), mStateCallback, mBackgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } }
三、内部类
只有一个 CameraDevice.StateCallback
的内部类,当相机状态发生变化时,会调用该类相应的回调方法。
相应的回调方法介绍在上面的示例中已经说明了,下面介绍一下 onError
回调方法中相应的错误码把:
错误码 | 描述 |
---|---|
CameraDevice.StateCallback.ERROR_CAMERA_IN_USE | 当前相机设备已经在一个更高优先级的地方打开了 |
CameraDevice.StateCallback.ERROR_MAX_CAMERAS_IN_USE | 已打开相机数量到上限了,无法再打开新的相机了 |
CameraDevice.StateCallback.ERROR_CAMERA_DISABLED | 由于相关设备策略该相机设备无法打开,详细可见 DevicePolicyManager 的 setCameraDisabled(ComponentName, boolean) 方法 |
CameraDevice.StateCallback.ERROR_CAMERA_DEVICE | 相机设备发生了一个致命错误 |
CameraDevice.StateCallback.ERROR_CAMERA_SERVICE | 相机服务发生了一个致命错误 |
四、常用方法
1. void close()
关闭对应的相机设备。
2. CaptureRequest.Builder createCaptureRequest(int templateType)
使用指定模板创建一个 CaptureRequest.Builder
用于新的捕获请求构建。
templateType | 描述 | 适用性 |
---|---|---|
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 的相机设备 |
3. void createCaptureSession(List outputs, CameraCaptureSession.StateCallback callback, Handler handler)
使用一个指定的 Surface 输出列表创建一个相机捕捉会话。
参数说明:
- outputs : 输出的 Surface 集合,每个 CaptureRequest 的输出 Surface 都应该是 outputs 的一个子元素。
- callback : 创建会话的回调。成功时将调用 CameraCaptureSession.StateCallback 的
onConfigured(CameraCaptureSession session)
方法。 - handler : 指定回调执行的线程,传 null 时默认使用当前线程的 Looper。
4. String getId()
获得当前相机设备的 id。
5. 示例
针对第二条和第三条,简单的使用如下:
try { // templateType 使用 TEMPLATE_PREVIEW,即创建一个相机预览请求 mCaptureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); mCaptureRequestBuilder.addTarget(mPreviewSurface); // 设置预览输出的 Surface // mPreviewSurface 是用于预览输出的 Surface // mImageReader.getSurface() 是用于拍照输出的 Surface mCameraDevice.createCaptureSession(Arrays.asList(mPreviewSurface, mImageReader.getSurface()), new CameraCaptureSession.StateCallback() { @Override public void onConfigured(@NonNull CameraCaptureSession session) { if (mCameraDevice == null) { return; } mCaptureSession = session; try { // 设置连续自动对焦 mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); // 设置关闭闪光灯 mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.FLASH_MODE_OFF); // 生成一个预览的请求 mPreviewRequest = mPreviewRequestBuilder.build(); // 开始预览,即设置反复请求 mCaptureSession.setRepeatingRequest(mPreviewRequest, null, mBackgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } @Override public void onConfigureFailed(@NonNull CameraCaptureSession session) { Log.e(TAG, "ConfigureFailed."); } }, mBackgroundHandler);} catch (CameraAccessException e) { e.printStackTrace();}
五、硬件支持等级
上面介绍适用性时提到了硬件支持级别。在 Camera2 中,相机设备支持的硬件等级有
LEVEL_3 > FULL > LIMIT > LEGACY
对于大多数的手机而言,都会支持到 FULL
或 LIMIT
。当支持到 FULL
等级的相机设备,将拥有比旧 API 强大的新特性,如 30fps 全高清连拍,帧之间的手动设置,RAW 格式的图片拍摄,快门零延迟以及视频速拍等,否则和旧 API 功能差别不大。
获取方式:
通过 CameraCharacteristics
类获取相机设备的特性,包括硬件等级的支持等级.
CameraCharacteristics characteristics = mCameraManager.getCameraCharacteristics(mCameraId);int hardwareLevel = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
更多相关文章
- 通过ijetty获取android设备的截图
- [转]]Android 应用签名提权方法
- 【Android】android开发---实现屏幕旋转的两种方法
- Android-缓存数据保存-通用方法
- Android 中 ListView Adapter getView 被多次调用问题 解决方法
- Android监听来电和去电的实现方法
- Android 屏幕的旋转 onConfigurationChanged方法
- 查看android里的数据库的内容的方法
- 让android定时关机的实现方法