Android使用Camera2打造自定义相机

本文介绍了Android 5.0引入的Camera2 API,它提供了对相机的全面控制,替代了过时的Camera API。文章详细讲解了Camera2的包架构、核心类如CameraManager、CameraDevice、CameraCharacteristics、CameraCaptureSession及其工作流程。通过创建CaptureRequest,设置预览和拍照参数,结合回调机制实现自定义相机功能。最后,强调了实际应用中掌握Camera2的重要性。
摘要由CSDN通过智能技术生成

从5.0开始(API Level 21),可以完全控制Android设备相机的新api Camera2(android.hardware.Camera2)被引入了进来。在以前的Camera api(android.hardware.Camera)中,对相机的手动控制需要更改系统才能实现,而且api也不友好。不过老的Camera API在5.0上已经过时,在未来的app开发中推荐的是Camera2 API。

1、Camera2介绍

在Camera类中我们多是使用这个类的对象去调用方法,而Camera2则是使用多个类去设置,功能更加强大。

Camera2包架构:

Google采用了pipeline(管道)的概念,将Camera Device相机设备和Android Device安卓设备连接起来, Android Device通过管道发送CaptureRequest拍照请求给Camera Device,Camera Device通过管道返回CameraMetadata数据给Android Device,这一切建立在一个叫作CameraCaptureSession的会话中。

基本上我们需要使用的就是这些类啦。其中CameraManager是所有相机设备(CameraDevice)的管理者,要枚举,查询和打开可用的相机设备,就获取CameraManager实例。

单个CameraDevices提供一组静态属性信息,描述硬件设备以及设备的可用设置和输出参数。该信息通过CameraCharacteristics对象提供,可通过getCameraCharacteristics(String)获得。

CameraCharacteristics是CameraDevice的属性描述类,在CameraCharacteristics中可以进行相机设备功能的详细设定(当然了,首先你得确定你的相机设备支持这些功能才行)。

要从相机设备捕获或流式传输图像,应用程序必须首先使用createCaptureSession(List,CameraCaptureSession.StateCallback,Handler)与相机设备一起使用一组输出Surfaces创建摄像机捕获会话。每个Surface必须预先配置适当的大小和格式(如果适用)以匹配相机设备可用的大小和格式。目标Surface可以从各种类获得。

CameraCaptureSession:这是一个非常重要的API,当程序需要预览、拍照时,都需要先通过该类的实例创建Session。而且不管预览还是拍照,也都是由该对象的方法进行控制的,其中控制预览的方法为setRepeatingRequest();控制拍照的方法为capture()。

通常,相机预览图像将发送到SurfaceView或TextureView(通过其SurfaceTexture)。

然后,应用程序需要构建一个CaptureRequest,它定义了相机设备捕获单个映像所需的所有捕获参数。该请求还列出了哪些配置的输出表面应该用作此捕获的目标。 CameraDevice具有用于为给定用例创建请求构建器的工厂方法,针对应用程序正在运行的Android设备进行了优化。

CameraRequest和CameraRequest.Builder:当程序调用setRepeatingRequest()方法进行预览时,或调用capture()方法进行拍照时,都需要传入CameraRequest参数。CameraRequest代表了一次捕获请求,用于描述捕获图片的各种参数设置,比如对焦模式、曝光模式……总之,程序需要对照片所做的各种控制,都通过CameraRequest参数进行设置。CameraRequest.Builder则负责生成CameraRequest对象。

一旦请求被建立,它可以交给主动捕获会话进行单次捕获或无休止地重复使用。处理请求后,相机设备将产生一个TotalCaptureResult对象,该对象包含有关拍摄时相机设备状态的信息以及使用的最终设置。如果需要舍入或解决矛盾的参数,这些请求可能会有所不同。相机设备还会将图像数据帧发送到请求中包括的每个输出表面。这些相对于输出CaptureResult是异步产生的,有时候稍后会产生。

类图中有着三个重要的callback,其中CameraCaptureSession.CaptureCallback将处理预览和拍照图片的工作,需要重点对待。

这两幅对Camera2接口使用的流程介绍我们综合起来看会有更深的理解。

  1. 可以看出调用openCamera方法后会回调CameraDevice.StateCallback这个方法,在该方法里重写onOpened函数。
  2. 在onOpened方法中调用createCaptureSession,该方法又回调CameraCaptureSession.StateCallback方法。
  3. 在CameraCaptureSession.StateCallback中重写onConfigured方法,设置setRepeatingRequest方法(也就是开启预览)。
  4. setRepeatingRequest又会回调 CameraCaptureSession.CaptureCallback方法。
  5. 重写CameraCaptureSession.CaptureCallback中的onCaptureCompleted方法,result就是未经过处理的元数据了。

顺便提一下CameraCaptureSession.CaptureCallback中的onCaptureProgressed方法很明显是在Capture过程中的,也就是在onCaptureCompleted之前,所以,在这之前想对图像干什么就看你的了,像美颜等操作就可以在这个方法中实现了。

可以看出Camera2相机使用的逻辑还是比较简单的,其实就是3个Callback函数的回调,先说一下:setRepeatingRequest和capture方法其实都是向相机设备发送获取图像的请求,但是capture就获取那么一次,而setRepeatingRequest就是不停的获取图像数据,所以呢,使用capture就想拍照一样,图像就停在那里了,但是setRepeatingRequest一直在发送和获取,所以需要连拍的时候就调用它,然后在onCaptureCompleted中保存图像就行了。(注意了,图像的预览也是用的setRepeatingRequest,只是你不处理数据就行了)。

通过上面对Camera2的API的分析,我们可以知道控制拍照的大致步骤为:

调用CameraManager的openCamera(String cameraId, CameraDevice.StateCallback callback, Handler handler)方法打开指定摄像头。该方法的第一个参数代表要打开的摄像头ID;第二个参数用于监听摄像头的状态;第三个参数代表执行callback的Handler,如果程序希望直接在当前线程中执行callback,则可将handler参数设为null。
当摄像头被打开之后,程序即可获取CameraDevice—即根据摄像头ID获取了指定摄像头设备,然后调用CameraDevice的createCaptureSession(List outputs, CameraCaptureSession. StateCallback callback,Handler handler)方法来创建CameraCaptureSession。该方法的第一个参数是一个List集合,封装了所有需要从该摄像头获取图片的Surface,第二个参数用于监听CameraCaptureSession的创建过程;第三个参数代表执行callback的Handler,如果程序希望直接在当前线程中执行callback,则可将handler参数设为null。
不管预览还是拍照,程序都调用CameraDevice的createCaptureRequest(int templateType)方法创建CaptureRequest.Builder,该方法支持TEMPLATE_PREVIEW(预览)、TEMPLATE_RECORD(拍摄视频)、TEMPLATE_STILL_CAPTURE(拍照)等参数。
通过第3步所调用方法返回的CaptureRequest.Builder设置拍照的各种参数,比如对焦模式、曝光模式等。
调用CaptureRequest.Builder的build()方法即可得到CaptureRequest对象

  • 11
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值