Camera2解剖

Camera2

在这里插入图片描述

使用流程:

  • 初始化并启动HandlerThread(因为创建会话是好时的操作不宜放在主线程)
  • 实现相关Surface的回调(是为了能在相关Surface可以用的时候自动开启预览)
  • 检查相机权限(android.permission.CAMERA)
  • cameraManager = (CameraManager) getSystemService(CAMERA_SERVICE);
  • cameraManager.getCameraIdList():获取相机硬件id集合
  • cameraManager.getCameraCharacteristics(cameraId):获取相机信息
  • cameraManager.openCamera(cameraId,cameraCallback,null); 开启相机
  • CameraDevice.StateCallback回调中获取cameraDevice
  • cameraDevice.createCaptureSession(surfaces,newCameraCaptureSession.StateCallback(),null)
    创建捕获会话,surfaces作为捕获的图像数据的输出的目标
  • CameraCaptureSession.StateCallback回调中获取到CameraCaptureSession
  • CaptureRequest.Builder 创建请求,通过键值对的方式设置参数
  • cameraCaptureSession.setRepeatingRequest(previewRequest, captureCallback, mBackgroundHandler); 发送请求

Camera2 主要角色之间的联系
CameraManager处于顶层管理位置负责检测获取所有摄像头及其特性和传入指定的CameraDevice.StateCallback回调打开指定摄像头,CameraDevice是负责管理抽象对象,包括监听Camera 的状态回调CameraDevice.StateCallback、创建CameraCaptureSessionCameraRequestCameraCaptureSession用于描述一次图像捕获操作,主要负责监听自己会话的状态回调CameraCaptureSession.StateCallbackCameraCaptureSession.CaptureCallback捕获回调,还有发送处理CameraRequestCameraRequest则可以看成是一个”JavaBean”的作用用于描述希望什么样的配置来处理这次请求;最后三个回调用于监听对应的状态。

关键类:
在这里插入图片描述

  1. CameraManager

相机管理器,在Camera打开之前主要操作CameraManager,打开后主要操作CameraCaptureSession。
和其他系统服务一样通过 Context.getSystemService(CameraManager.class ) 或者Context.getSystemService(Context.CAMERA_SERVICE) 来完成初始化,主要用于管理系统摄像头:

  • 通过getCameraIdList()方法获取Android设备的摄像头列表
  • openCamera(String cameraId, CameraDevice.StateCallback callback, Handler handler)打开指定Id的摄像头
  1. CameraCharacteristics 摄像头属性,相当于Camera1的CameraInfo。通过获取Camera属性信息,配置Camera输 出,如FPS,大小,旋转等。
    mCameraManager.getCameraCharacteristics(currentCameraId);获取摄像头的详细参数和支持的功能

  2. CameraDevice
    用于创建CameraCaptureSession和关闭摄像头。cameraManager.openCamera(cameraId,cameraCallback,null);
    cameraCallback的回调中获取到实例对象

    • 通过CameraDevice.StateCallback监听摄像头的状态(主要包括onOpened、onClosed、onDisconnected、onErro四种状态)
    • 管理CameraCaptureSession
      通过方法createCaptureSession(List outputs, CameraCaptureSession.StateCallback callback, Handler handler)方法和createReprocessableCaptureSession(InputConfiguration inputConfig, List outputs, CameraCaptureSession.StateCallback callback, Handler handler)方法创建会话 (其中第三个参数: 应在其上调用回调的处理程序,或null以使用当前线程的循环器),通常会在CameraDevice.StateCallback中调用对应方法创建预览会话。
  3. CameraCaptureSession
    相机捕获会话,CameraCaptureSession建立了一个和Camera硬件设备的会话通道,可以通过这个会话向Camera发送请求获取图像。
    setRepeatingRequest():控制预览;capture():控制拍照。
    系统向摄像头发送 Capture 请求,而摄像头会返回 CameraMetadata,这一切都是在由对应的CameraDevice创建的CameraCaptureSession 会话完成,当程序需要预览、拍照、再次预览时,都需要先通过会话。CameraCaptureSession一旦被创建,直到对应的CameraDevice关闭才会死掉。虽然CameraCaptureSession会话用于从摄像头中捕获图像,但是只有同一个会话才能再次从同一摄像头中捕获图像。另外,创建会话是一项耗时的异步操作,可能需要几百毫秒,因为它需要配置相机设备的内部管道并分配内存缓冲区以将图像发送到所需的目标,因而createCaptureSession和createReprocessableCaptureSession会将随时可用的CameraCaptureSession发送到提供的监听器的onConfigured回调中。如果无法完成配置,则触发onConfigureFailed回调,并且会话将不会变为活动状态。最后需要注意的是,如果摄像头设备创建了一个新的会话,那么上一个会话是被关闭的,并且会回调与其关联的onClosed,如果不处理好,当会话关闭之后再次调用会话的对应方法那么所有方法将会跑出IllegalStateException异常。关闭的会话清除任何重复的请求(和调用了stopRepeating()方法类似),但是在新创建的会话接管并重新配置摄像机设备之前,关闭的会话仍然会正常完成所有正在进行的捕获请求。简而言之,在Camera2中CameraCaptureSession承担很重要的角色:

    • 管理CameraCaptureSession.StateCallback状态回调,用于接收有关CameraCaptureSession状态的更新的回调对象,主要回调方法有两个,当CameraDevice 完成配置,对应的会话开始处理捕获请求时触发onConfigured(CameraCaptureSession session)方法,反之配置失败时候触发onConfigureFailed(CameraCaptureSession session)方法。
    • 管理CameraCaptureSession.CaptureCallback捕获回调,用于接收捕获请求状态的回调,当请求触发捕获已启动时;捕获完成时;在捕获图像时发生错误的情况下;都会触发该回调对应的方法。
    • 调用方法capture(CaptureRequest request, CameraCaptureSession.CaptureCallback listener, Handler handler)提交捕获图像请求(Submit a request for an image to be captured by the camera device.)即拍照,其中该请求定义了捕获单个图像的所有参数,包括传感器,镜头,闪光灯和后处理参数,每一次请求的结果将产生一个CaptureResult,可以为一个或多个Surface生成新的帧,然后通过CaptureRequest.Builder的addTarget(Surface)方法附着到对应的Surface上显示,而且这个参数Surface必须是会话创建时候的一个子集,会话一次可以处理多个常规和重新处理请求。但如果只有常规请求或重新处理请求在进行,则以先进先出的顺序处理它们;如果两者都在进行中则分别以各自的先进先出顺序处理他们;然而,处理常规请求和重新处理请求的顺序并不是特定的,换言之,一个常规请求在下一个常规请求提交前被处理,同理重新处理请求也一样,但是一个常规请求不一定是在下一个重新处理请求提交之前被处理。通过capture方法提交的请求处理优先级比通过其他方式( setRepeatingRequest(CaptureRequest, CameraCaptureSession.CaptureCallback, Handler) 或者setRepeatingBurst(List, CameraCaptureSession.CaptureCallback, Handler))提交的请求的处理优先级高,一旦当前的repeat / repeatBurst处理完成,就会被处理。最后一点,所有CaptureSession可用于从相机捕获图像,但只有由createReprocessableCaptureSession创建的会话才可以提交重新处理捕获请求,将重新处理请求提交到常规捕获会话将导致IllegalArgumentException。
    • 通过调用方法setRepeatingRequest(CaptureRequest request, CameraCaptureSession.CaptureCallback listener, Handler handler)请求不断重复捕获图像,即实现预览。通过方法调用stopRepeating()实现停止捕获图像,即停止预览。
  4. CameraRequest和CaptureRequest.Builder
    CameraRequest代表了一次捕获请求
    CameraRequest.Builder用于描述捕获图片的各种参数设置,包含捕获硬件(传感器,镜头,闪存),对焦模式、曝光模式,处理流水线,控制算法和输出缓冲区的配置。
    当程序调用setRepeatingRequest()方法进行预览时,或调用capture()方法进行拍照时,都需要传入CameraRequest参数。CameraRequest可以通过CameraRequest.Builder来进行初始化,通过调用createCaptureRequest来获得。

  5. CaptureResult
    CaptureRequest描述是从图像传感器捕获单个图像的结果的子集的对象。当CaptureRequest被处理之后由CameraDevice生成。

两篇对camera2API学习很好的文章
Camera2详解之一 API学习


版权声明:本文为weixin_46083166原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。