
从 Android 50 开始,Google 引入了一套全新的相机框架 Camera2(androidhardwarecamera2)并且废弃了旧的相机框架 Camera1(androidhardwareCamera)。作为一个专门从事相机应用开发的开发者来说,这一刻我等了太久了,Camera1 那寥寥无几的 API 和极差的灵活性早已不能满足日益复杂的相机功能开发。Camera2 的出现给相机应用程序带来了巨大的变革,因为它的目的是为了给应用层提供更多的相机控制权限,从而构建出更高质量的相机应用程序。本文是 Camera2 教程的开篇作,本章将介绍以下几个内容:
Camera2 的 API 模型被设计成一个 Pipeline(管道),它按顺序处理每一帧的请求并返回请求结果给客户端。下面这张来自官方的图展示了 Pipeline 的工作流程,我们会通过一个简单的例子详细解释这张图。
为了解释上面的示意图,假设我们想要同时拍摄两张不同尺寸的,并且在拍摄的过程中闪光灯必须亮起来。整个拍摄流程如下:
一个新的 CaptureRequest 会被放入一个被称作 Pending Request Queue 的队列中等待被执行,当 In-Flight Capture Queue 队列空闲的时候就会从 Pending Request Queue 获取若干个待处理的 CaptureRequest,并且根据每一个 CaptureRequest 的配置进行 Capture *** 作。最后我们从不同尺寸的 Surface 中获取数据并且还会得到一个包含了很多与本次拍照相关的信息的 CaptureResult,流程结束。
相机功能的强大与否和硬件息息相关,不同厂商对 Camera2 的支持程度也不同,所以 Camera2 定义了一个叫做 Supported Hardware Level 的重要概念,其作用是将不同设备上的 Camera2 根据功能的支持情况划分成多个不同级别以便开发者能够大概了解当前设备上 Camera2 的支持情况。截止到 Android P 为止,从低到高一共有 LEGACY、LIMITED、FULL 和 LEVEL_3 四个级别:
相机的所有 *** 作和参数配置最终都是服务于图像捕获,例如对焦是为了让某一个区域的图像更加清晰,调节曝光补偿是为了调节图像的亮度。因此,在 Camera2 里面所有的相机 *** 作和参数配置都被抽象成 Capture(捕获),所以不要简单的把 Capture 直接理解成是拍照,因为 Capture *** 作可能仅仅是为了让预览画面更清晰而进行对焦而已。如果你熟悉 Camera1,那你可能会问 setFlashMode() 在哪? setFocusMode() 在哪? takePicture() 在哪?告诉你,它们都是通过 Capture 来实现的。
Capture 从执行方式上又被细分为单次模式、多次模式和重复模式三种,我们来一一解释下:
CameraManager 是一个负责查询和建立相机连接的系统服务,它的功能不多,这里列出几个 CameraManager 的关键功能:
CameraCharacteristics 是一个只读的相机信息提供者,其内部携带大量的相机信息,包括代表相机朝向的 LENS_FACING ;判断闪光灯是否可用的 FLASH_INFO_AVAILABLE ;获取所有可用 AE 模式的 CONTROL_AE_AVAILABLE_MODES 等等。如果你对 Camera1 比较熟悉,那么 CameraCharacteristics 有点像 Camera1 的 CameraCameraInfo 或者 CameraParameters 。
CameraDevice 代表当前连接的相机设备,它的职责有以下四个:
熟悉 Camera1 的人可能会说 CameraDevice 就是 Camera1 的 Camera 类,实则不是,Camera 类几乎负责了所有相机的 *** 作,而 CameraDevice 的功能则十分的单一,就是只负责建立相机连接的事务,而更加细化的相机 *** 作则交给了稍后会介绍的 CameraCaptureSession。
Surface 是一块用于填充图像数据的内存空间,例如你可以使用 SurfaceView 的 Surface 接收每一帧预览数据用于显示预览画面,也可以使用 ImageReader 的 Surface 接收 JPEG 或 YUV 数据。每一个 Surface 都可以有自己的尺寸和数据格式,你可以从 CameraCharacteristics 获取某一个数据格式支持的尺寸列表。
CameraCaptureSession 实际上就是配置了目标 Surface 的 Pipeline 实例,我们在使用相机功能之前必须先创建 CameraCaptureSession 实例。一个 CameraDevice 一次只能开启一个 CameraCaptureSession,绝大部分的相机 *** 作都是通过向 CameraCaptureSession 提交一个 Capture 请求实现的,例如拍照、连拍、设置闪光灯模式、触摸对焦、显示预览画面等等。
CaptureRequest 是向 CameraCaptureSession 提交 Capture 请求时的信息载体,其内部包括了本次 Capture 的参数配置和接收图像数据的 Surface。CaptureRequest 可以配置的信息非常多,包括图像格式、图像分辨率、传感器控制、闪光灯控制、3A 控制等等,可以说绝大部分的相机参数都是通过 CaptureRequest 配置的。值得注意的是每一个 CaptureRequest 表示一帧画面的 *** 作,这意味着你可以精确控制每一帧的 Capture *** 作。
CaptureResult 是每一次 Capture *** 作的结果,里面包括了很多状态信息,包括闪光灯状态、对焦状态、时间戳等等。例如你可以在拍照完成的时候,通过 CaptureResult 获取本次拍照时的对焦状态和时间戳。需要注意的是,CaptureResult 并不包含任何图像数据,前面我们在介绍 Surface 的时候说了,图像数据都是从 Surface 获取的。
如果要我给出强有力的理由解释为什么要使用 Camera2,那么通过 Camera2 提供的高级特性可以构建出更加高质量的相机应用程序应该是最佳理由了。
如果你熟悉 Camera1,并且打算从 Camera1 迁移到 Camera2 的话,希望以下几个建议可以对你起到帮助:
本章到此结束,主要是介绍了 Camera2 的一些基础概念,让大家能够基本了解 Camera2 的工作流程和基础概念,并且知道使用 Camera2 能够做些什么。如果你对 Camera2 还是感到很陌生,不要紧,后续的教程会带领大家逐步深入了解 Camera2。
点击想要参数下方会有变量名 使用变量名来获取。
如有任何关于Teledyne Dalsa的问题或需要敬请联络51camera志强视觉科技 —— >
Uri
uri
=
datagetData();
这样是可以得到相片的位置的,但是比如使用camera360就不能再拍完照片后不能返回到我的界面,一直卡在camera360那个位置
一切源于在项目过程中的一个Bug:我的需求是在MainActivity 实现自动预览,也可以点击跳到签到SignedActivity去实现拍照签到,第一次进入界面的时候都是正常的,但是有时候返回来的时候预览失败,即从MainActivity跳转到SignedActivity偶尔预览失败和从SignedActivity返回MainActivity偶尔失败,都是报(CAMERA_IN_USE)ERRO=1的错误,奇怪的是的的确确做了完全释放 *** 作,加上以前用的更多的是Camera api 对于Camer2 的机制没有完整去研究过,一下子懵了,于是乎先去找了Stack Overflow,查到一个解决方案是:"我弃用了新API,换回旧API",ORZ,找了其他的也没有答案,可是我不服呀,我就把官方的文档全部啃了一遍,于是乎便有了以下的理解,我想如果你不懂得怎么使用Camera2的话,这篇绝对值得你去阅读,你会发现Camera2 并非像大多数说得那样使用起来很复杂。
全新的androidhardwareCamera2 。Android 50对拍照API进行了全新的设计,新增了全新设计的Camera 2 API,这些API不仅大幅提高了Android系统拍照的功能,还能支持RAW照片输出,甚至允许程序调整相机的对焦模式、曝光模式、快门等。
在Camera2 架构在核心参与类角色有: CameraManager 、 CameraDevice 、 CameraCharacteristics 、 CameraRequest与CameraRequestBuilder 、 CameraCaptureSession 以及 CaptureResult 。
位于androidhardwarecamera2CameraManager下,也是Android 21(50)添加的,和其他系统服务一样通过 ContextgetSystemService(CameraManagerclass ) 或者 ContextgetSystemService(ContextCAMERA_SERVICE) 来完成初始化,主要用于管理系统摄像头:
CameraDevice是Camera2中抽象出来的一个对象,直接与系统硬件摄像头相联系。因为不可能所有的摄像头都会支持高级功能(即摄像头功能可被分为limit 和full 两个级别),当摄像头处于limited 级别时候,此时Camera2和早期的Camera功能差不多,除此之外在Camera2架构中,CameraDevice还承担其他两项重要任务:
正如前面所说, 系统向摄像头发送 Capture 请求,而摄像头会返回 CameraMetadata,这一切都是在由对应的CameraDevice创建的CameraCaptureSession 会话完成 ,当程序需要预览、拍照、再次预览时,都需要先通过会话。(A configured capture session for a CameraDevice , used for capturing images from the camera or reprocessing images captured from the camera in the same session previouslyA CameraCaptureSession is created by providing a set of target output surfaces to createCaptureSession , or by providing an InputConfiguration and a set of target output surfaces to createReprocessableCaptureSession for a reprocessable capture session Once created, the session is active until a new session is created by the camera device, or the camera device is closed)CameraCaptureSession一旦被创建,直到对应的CameraDevice关闭才会死掉。虽然CameraCaptureSession会话用于从摄像头中捕获图像,但是只有同一个会话才能再次从同一摄像头中捕获图像。另外, 创建会话是一项耗时的异步 *** 作,可能需要几百毫秒 ,因为它需要配置相机设备的内部管道并分配内存缓冲区以将图像发送到所需的目标,因而createCaptureSession和createReprocessableCaptureSession会将随时可用的CameraCaptureSession发送到提供的监听器的onConfigured回调中。如果 无法完成配置,则触发onConfigureFailed回调 ,并且会话将不会变为活动状态。最后需要注意的是,如果 摄像头设备创建了一个新的会话,那么上一个会话是被关闭的,并且会回调与其关联的onClosed ,如果不处理好,当会话关闭之后再次调用会话的对应方法那么所有方法将会跑出IllegalStateException异常。关闭的会话清除任何重复的请求(和调用了stopRepeating()方法类似),但是在新创建的会话接管并重新配置摄像机设备之前,关闭的会话仍然会正常完成所有正在进行的捕获请求。简而言之,在Camera2中CameraCaptureSession承担很重要的角色:
描述Cameradevice属性的对象,可以使用CameraManager通过getCameraCharacteristics(String cameraId)进行查询。
CameraRequest代表了一次捕获请求, 而CameraRequestBuilder用于描述捕获的各种参数设置,包含捕获硬件(传感器,镜头,闪存),对焦模式、曝光模式,处理流水线,控制算法和输出缓冲区的配置。 ,然后传递到对应的会话中进行设置, CameraRequestBuilder则负责生成CameraRequest对象 。当程序调用setRepeatingRequest()方法进行预览时,或调用capture()方法进行拍照时,都需要传入CameraRequest参数。CameraRequest可以通过CameraRequestBuilder来进行初始化,通过调用createCaptureRequest来获得。
CaptureRequest描述是从图像传感器捕获单个图像的结果的子集的对象。(CaptureResults are produced by a CameraDevice after processing a CaptureRequest)当CaptureRequest被处理之后由CameraDevice生成。
CameraManager 处于顶层管理位置负责 检测获取所有摄像头及其特性 和 传入指定的CameraDeviceStateCallback回调打开指定摄像头 , CameraDevice 是负责管理抽象对象,包括 监听Camera 的状态回调CameraDeviceStateCallback 、 创建CameraCaptureSession和CameraRequest , CameraCaptureSession 用于描述一次图像捕获 *** 作,主要负责 监听自己会话的状态回调CameraCaptureSessionStateCallback 和 CameraCaptureSessionCaptureCallback捕获回调 ,还有 发送处理CameraRequest ; CameraRequest 则可以看成是一个"JavaBean"的作用用于描述希望什么样的配置来处理这次请求;最后三个回调用于监听对应的状态。
CameraManager 处于顶层管理位置负责检测 检测获取所有摄像头并设置输出参数,传入指定的CameraDeviceStateCallback回调,然后打开指定摄像头,并触发CameraDeviceStateCallback中的onOpened方法,并在onOpened方法里开始通过调用创建预览会话, ,CameraDevice负责创建请求 CameraCharacteristics 、 CameraRequest与CameraRequestBuilder 、 CameraCaptureSession 以及 CaptureResult 则可以看成是一个JavaBean的作用用于描述以什么样的配置来处理这次请求。
Camera2Helper类只是简单的封装了下,为了让Camera2的初始化和Activity 高度分离,这个类只是Demo 阶段部分有待优化,另外结合我具体的业务,对于大小有限制,所以我都是默认采用采样压缩率方式对进行压缩
以上就是关于Android Camera2 教程 · 第一章 · 概览全部的内容,包括:Android Camera2 教程 · 第一章 · 概览、dalsa相机二次开发时如何获取参数范围、android 怎么得到相机的照片啊等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)