Camera框架初识

来源:互联网 发布:nginx 500错误日志 编辑:程序博客网 时间:2024/06/05 16:36

Camera类被用于获取图片设置,start/stop 预览,快照图片,恢复视频编码的帧,Camera是一个client对于Camera Service来说,将管理Camera 硬件相关,
为了使用设备的camera, 须要在Manifest中加上相应的权限,如你须要自动聚焦功能,在Manifest.xml须加入

<uses-permission android:name="android.permission.CAMERA" /><uses-feature android:name="android.hardware.camera" /><uses-feature android:name="android.hardware.camera.autofocus" />

Camera拍照

用Camera去拍照,将遵循以下几个步骤:

  • 获得一个Camera的实例,通过open方法
  • 如果必要的话,可以修改一些默认参数
  • 通过初始化SurfaceHolder去setPreviewDisplay(SurfaceHolder),没有Surface, camera不能开始预览
  • 调用startPreview方法开始更新预览的surface,在拍照前,预览(preview)必须被开启。
  • 当你想开始拍照时,使用takePicture(Camera.ShutterCallback,
    Camera.PictureCallback, Camera.PictureCallback, Camera.PictureCallback), 等待回调提供真实的图像数据
  • 当拍完一张照片时,预览(preview)将会停止,当你想要拍更多的照片时,须要再一次调用startPreview方法
  • 当调用stopPreview方法时,将停止更新预览的surface
  • 当调用release方法时,将马上释放camera

Camera录像

以上是拍照过程,当如果切换成视频录制模式时,将遵循以下步骤:

  • 获取一个初始化Camera,且开始预览
  • 调用unlock方法允许media进程去访问camera
  • 通过camera去setCamera(Camera),了解更多,可看MediaRecorder
  • 当完成录制时,调用reconnect方法重新获取且重新lock camera
  • 调用stopPreview()方法且release方法时,作为以上描述
  • 这个类是一个非线程安全类,意味着在被使用任何工作线程中,大多数长运行操作(preview,focus,photo capture 等)发生,异步调用回调是必要的。回调被调用在事件线程,Camera方法决不能一次被多个线程调用
  • 不同的安卓设备可能有不同的硬件规格,如像素的评级和自动对焦功能。


实例

使用Camera有两种方式:通过Intent使用已有的app和通过Camera构建自己的app。通过Camera API的方式拍照。

通过Camera API方式拍照需要引入几个关键的类:

  • Camera类:最主要的类,用于管理Camera设备,本文中主要用到以下方法:

    • open():通过open方法获取Camera实例。
    • setPreviewDisplay(SurfaceHolder):设置预览拍照
    • startPreview():开始预览
    • stopPreview():停止预览
    • release():释放Camera实例
    • takePicture(Camera.ShutterCallback shutter, Camera.PictureCallback raw, Camera.PictureCallback jpeg):这个是拍照要执行的方法,包含了三个回调参数。Shutter是快门按下时的回调,raw是获取拍照原始数据的回调,jpeg是获取经过压缩成jpg格式的图像数据。在本文中需要实现最后一个回调,参见下面。
    • Camera.PictureCallback接口:该回调接口包含了一个onPictureTaken(byte[]data, Camera camera)方法。在这个方法中可以保存图像数据。
  • SurfaceView类:用于控制预览界面

  • SurfaceHolder.Callback接口:用于处理预览的事件,需实现如下三个方法:

    • surfaceCreated(SurfaceHolderholder):预览界面创建时调用,每次界面改变后都会重新创建,需要获取相机资源并设置SurfaceHolder。
    • surfaceChanged(SurfaceHolderholder, int format, int width, int height):预览界面发生变化时调用,每次界面发生变化之后需要重新启动预览。
    • surfaceDestroyed(SurfaceHolderholder):预览销毁时调用,停止预览,释放相应资源。

通过Camera方式来实现拍照

通过Camera方式 会比通过Intent方式获得更为丰富的功能。通常创建一个定制化的Camera需要如下步骤:

(1) 通过Camera.open()来获取Camera实例。
(2) 创建Preview类,需要继承SurfaceView类并实现SurfaceHolder.Callback接口。
(3) 为相机设置Preview
(4) 构建一个Preview的Layout来预览相机;
(5) 为拍照建立Listener以获取拍照后的回调;
(6) 拍照并保存文件;
(7) 释放Camera。


Camera2下各个Class介绍

接下来接介绍Camera2下的各个类:

  • CmaeraManager: 摄像头管理者,这是一个全新的系统管理者,专门用户检测系统摄像头,打开系统摄像头,除此之外,调用CameraManager的getCameraCharacteristics(String)方法即可获取指定摄像头的相关特性。
  • CameraCharacteristics:摄像头特性。该对象通过CameraManager来获取,用于描述特定摄像头所支持的各种特性。
  • CameraDevice:代表系统摄像头。该类的功能类似于早期的Camera类。
  • CameraCaptureSession:这是一个与摄像头建立会话的类,当程序需要预览、拍照时,都需要先通过该类的实例创建Session。而且不管预览还是拍照,也都是由该对象的方法进行控制的,其中控制预览的方法为setRepeatingRequest();控制拍照的方法为capture()。
    为了监听CameraCaptureSession的创建过程,以及监听CameraCaptureSession的拍照过程,Camera2 API为CameraCaptureSession提供了StateCallback、CaptureCallback等内部类。
  • CameraRequest和CameraRequest.Builder:当程序调用setRepeatingRequest()方法进行预览时,或调用capture()方法进行拍照时,都需要传入CameraRequest参数。CameraRequest代表了一次捕获请求,用于描述捕获图片的各种参数设置,比如对焦模式、曝光模式……程序需要对照片所做的各种控制,都通过CameraRequest参数进行设置。可以理解一个请求参数一样,CameraRequest.Builder则负责生成CameraRequest对象。

Camera2类图(局部)


 

其中CameraManager是所有相机设备(CameraDevice)的管理者,而每个CameraDevice自己会负责建立CameraCaptureSession以及建立CaptureRequest。CameraCharacteristics是CameraDevice的属性描述类,在CameraCharacteristics中可以进行相机设备功能的详细设定。

Camera2中3个重要的Callback

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



 


以上流程总结为:
  • 调用openCamera方法后会回调CameraDevice.StateCallback这个方法,在该方法里重写onOpened函数。在onOpened方法中调用createCaptureSession,该方法又回调CameraCaptureSession.StateCallback方法。
  • 在CameraCaptureSession.StateCallback中重写onConfigured方法,设置setRepeatingRequest方法(也就是开启预览了)。
    setRepeatingRequest又会回调
    CameraCaptureSession.CaptureCallback方法。
  • 重写CameraCaptureSession.CaptureCallback中的
    onCaptureCompleted方法,result就是未经过处理的元数据了。
  • 其中onCaptureProgressed方法是在Capture过程中的,像这类Progress,也就是在onCaptureCompleted之前,所以,在这之前相对图像干什么就看你的了,像美颜,美拍等操作就可以在这个方法中实现。

以上重点是3个Callback函数的回调

setRepeatingRequest和capture

接下来了解下:setRepeatingRequest和capture方法其实都是向相机设备发送获取图像的请求,但是capture就获取那么一次,而setRepeatingRequest就是不停的获取图像数据,所以呢,使用capture就想拍照一样,图像就停在那里,但是setRepeatingRequest一直在发送和获取,所以需要连拍的时候就调用它,然后在onCaptureCompleted中保存图像就行了。(注意了,图像的预览也是用的setRepeatingRequest,只是你不处理数据就行)


参考:

http://blog.csdn.net/hejjunlin/article/details/52751055


原创粉丝点击