android.hardware.camera2使用指南
来源:互联网 发布:mac u盘 200m 编辑:程序博客网 时间:2024/05/17 23:54
API 21中将原来的camera API弃用转而推荐使用新增的camera2 API,这是一个大的动作,因为新API换了架构,让开发者用起来更难了。
先来看看camera2包架构示意图:
这里引用了管道的概念将安卓设备和摄像头之间联通起来,系统向摄像头发送Capture请求,而摄像头会返回CameraMetadata。这一切建立在一个叫作CameraCaptureSession的会话中。
下面是camera2包中的主要类:
其中CameraManager是那个站在高处统管所有摄像投设备(CameraDevice)的管理者,而每个CameraDevice自己会负责建立CameraCaptureSession以及建立CaptureRequest。CameraCharacteristics是CameraDevice的属性描述类,非要做个对比的话,那么它与原来的CameraInfo有相似性。
类图中有着三个重要的callback,虽然这增加了阅读代码的难度,但是你必须要习惯,因为这是新包的风格。其中CameraCaptureSession.CaptureCallback将处理预览和拍照图片的工作,需要重点对待。
这些类是如何相互配合的?下面是简单的流程图。
我是用SurfaceView作为显示对象(当然还可以TextureView去显示,详见参考中的项目)
核心代码如下:
<code class="hljs java has-numbering"> mCameraManager = (CameraManager) <span class="hljs-keyword">this</span>.getSystemService(Context.CAMERA_SERVICE); mSurfaceView = (SurfaceView)findViewById(R.id.surfaceview); mSurfaceHolder = mSurfaceView.getHolder(); mSurfaceHolder.addCallback(<span class="hljs-keyword">new</span> SurfaceHolder.Callback() { <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">surfaceCreated</span>(SurfaceHolder holder) { initCameraAndPreview(); } });</code><ul style="display: block;" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li></ul>
<code class="hljs avrasm has-numbering"> private void initCameraAndPreview() { Log<span class="hljs-preprocessor">.d</span>(<span class="hljs-string">"linc"</span>,<span class="hljs-string">"init camera and preview"</span>)<span class="hljs-comment">;</span> HandlerThread handlerThread = new HandlerThread(<span class="hljs-string">"Camera2"</span>)<span class="hljs-comment">;</span> handlerThread<span class="hljs-preprocessor">.start</span>()<span class="hljs-comment">;</span> mHandler = new Handler(handlerThread<span class="hljs-preprocessor">.getLooper</span>())<span class="hljs-comment">;</span> try { mCameraId = <span class="hljs-string">""</span>+CameraCharacteristics<span class="hljs-preprocessor">.LENS</span>_FACING_FRONT<span class="hljs-comment">;</span> mImageReader = ImageReader<span class="hljs-preprocessor">.newInstance</span>(mSurfaceView<span class="hljs-preprocessor">.getWidth</span>(), mSurfaceView<span class="hljs-preprocessor">.getHeight</span>(), ImageFormat<span class="hljs-preprocessor">.JPEG</span>,<span class="hljs-comment">/*maxImages*/</span><span class="hljs-number">7</span>)<span class="hljs-comment">;</span> mImageReader<span class="hljs-preprocessor">.setOnImageAvailableListener</span>(mOnImageAvailableListener, mHandler)<span class="hljs-comment">;</span> mCameraManager<span class="hljs-preprocessor">.openCamera</span>(mCameraId, DeviceStateCallback, mHandler)<span class="hljs-comment">;</span> } catch (CameraAccessException e) { Log<span class="hljs-preprocessor">.e</span>(<span class="hljs-string">"linc"</span>, <span class="hljs-string">"open camera failed."</span> + e<span class="hljs-preprocessor">.getMessage</span>())<span class="hljs-comment">;</span> } }</code><ul style="display: block;" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li></ul>
<code class="hljs java has-numbering"><span class="hljs-keyword">private</span> CameraDevice.StateCallback DeviceStateCallback = <span class="hljs-keyword">new</span> CameraDevice.StateCallback() { <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onOpened</span>(CameraDevice camera) { Log.d(<span class="hljs-string">"linc"</span>,<span class="hljs-string">"DeviceStateCallback:camera was opend."</span>); mCameraOpenCloseLock.release(); mCameraDevice = camera; <span class="hljs-keyword">try</span> { createCameraCaptureSession(); } <span class="hljs-keyword">catch</span> (CameraAccessException e) { e.printStackTrace(); } } };</code><ul style="display: block;" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li></ul>
<code class="hljs avrasm has-numbering"> private void createCameraCaptureSession() throws CameraAccessException { Log<span class="hljs-preprocessor">.d</span>(<span class="hljs-string">"linc"</span>,<span class="hljs-string">"createCameraCaptureSession"</span>)<span class="hljs-comment">;</span> mPreviewBuilder = mCameraDevice<span class="hljs-preprocessor">.createCaptureRequest</span>(CameraDevice<span class="hljs-preprocessor">.TEMPLATE</span>_PREVIEW)<span class="hljs-comment">;</span> mPreviewBuilder<span class="hljs-preprocessor">.addTarget</span>(mSurfaceHolder<span class="hljs-preprocessor">.getSurface</span>())<span class="hljs-comment">;</span> mState = STATE_PREVIEW<span class="hljs-comment">;</span> mCameraDevice<span class="hljs-preprocessor">.createCaptureSession</span>( Arrays<span class="hljs-preprocessor">.asList</span>(mSurfaceHolder<span class="hljs-preprocessor">.getSurface</span>(), mImageReader<span class="hljs-preprocessor">.getSurface</span>()), mSessionPreviewStateCallback, mHandler)<span class="hljs-comment">;</span> }</code><ul style="display: block;" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li></ul>
<code class="hljs avrasm has-numbering">private CameraCaptureSession<span class="hljs-preprocessor">.StateCallback</span> mSessionPreviewStateCallback = new CameraCaptureSession<span class="hljs-preprocessor">.StateCallback</span>() { @Override public void onConfigured(CameraCaptureSession session) { Log<span class="hljs-preprocessor">.d</span>(<span class="hljs-string">"linc"</span>,<span class="hljs-string">"mSessionPreviewStateCallback onConfigured"</span>)<span class="hljs-comment">;</span> mSession = session<span class="hljs-comment">;</span> try { mPreviewBuilder<span class="hljs-preprocessor">.set</span>(CaptureRequest<span class="hljs-preprocessor">.CONTROL</span>_AF_MODE, CaptureRequest<span class="hljs-preprocessor">.CONTROL</span>_AF_MODE_CONTINUOUS_PICTURE)<span class="hljs-comment">;</span> mPreviewBuilder<span class="hljs-preprocessor">.set</span>(CaptureRequest<span class="hljs-preprocessor">.CONTROL</span>_AE_MODE, CaptureRequest<span class="hljs-preprocessor">.CONTROL</span>_AE_MODE_ON_AUTO_FLASH)<span class="hljs-comment">;</span> session<span class="hljs-preprocessor">.setRepeatingRequest</span>(mPreviewBuilder<span class="hljs-preprocessor">.build</span>(), mSessionCaptureCallback, mHandler)<span class="hljs-comment">;</span> } catch (CameraAccessException e) { e<span class="hljs-preprocessor">.printStackTrace</span>()<span class="hljs-comment">;</span> Log<span class="hljs-preprocessor">.e</span>(<span class="hljs-string">"linc"</span>,<span class="hljs-string">"set preview builder failed."</span>+e<span class="hljs-preprocessor">.getMessage</span>())<span class="hljs-comment">;</span> } } }<span class="hljs-comment">;</span></code><ul style="display: block;" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li></ul>
<code class="hljs java has-numbering"><span class="hljs-keyword">private</span> CameraCaptureSession.CaptureCallback mSessionCaptureCallback = <span class="hljs-keyword">new</span> CameraCaptureSession.CaptureCallback() { <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onCaptureCompleted</span>(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {<span class="hljs-comment">// Log.d("linc","mSessionCaptureCallback, onCaptureCompleted");</span> mSession = session; checkState(result); } <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onCaptureProgressed</span>(CameraCaptureSession session, CaptureRequest request, CaptureResult partialResult) { Log.d(<span class="hljs-string">"linc"</span>,<span class="hljs-string">"mSessionCaptureCallback, onCaptureProgressed"</span>); mSession = session; checkState(partialResult); } <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">checkState</span>(CaptureResult result) { <span class="hljs-keyword">switch</span> (mState) { <span class="hljs-keyword">case</span> STATE_PREVIEW: <span class="hljs-comment">// NOTHING</span> <span class="hljs-keyword">break</span>; <span class="hljs-keyword">case</span> STATE_WAITING_CAPTURE: <span class="hljs-keyword">int</span> afState = result.get(CaptureResult.CONTROL_AF_STATE); <span class="hljs-keyword">if</span> (CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED == afState || CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED == afState || CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED == afState || CaptureResult.CONTROL_AF_STATE_PASSIVE_UNFOCUSED == afState) { <span class="hljs-comment">//do something like save picture</span> } <span class="hljs-keyword">break</span>; } } };</code><ul style="display: block;" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li></ul>
按下capture按钮:
<code class="hljs cs has-numbering"> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onCapture</span>(View view) { <span class="hljs-keyword">try</span> { Log.i(<span class="hljs-string">"linc"</span>, <span class="hljs-string">"take picture"</span>); mState = STATE_WAITING_CAPTURE; mSession.setRepeatingRequest(mPreviewBuilder.build(), mSessionCaptureCallback, mHandler); } <span class="hljs-keyword">catch</span> (CameraAccessException e) { e.printStackTrace(); } }</code><ul style="display: block;" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li></ul>
测试用genemotion模拟器,直接调用笔记本的摄像头。
配置图如下:
demo界面如下图:
源码:
请参考github中的两个demo项目:
https://github.com/pinguo-yuyidong/Camera2
https://github.com/googlesamples/android-Camera2Basic
- android.hardware.camera2使用指南
- android.hardware.camera2使用指南
- android.hardware.camera2使用指南
- android.hardware.camera2使用指南
- android.hardware.camera2使用指南
- Android实战技巧之三十三:android.hardware.camera2使用指南
- Android实战技巧之三十三:android.hardware.camera2使用指南
- 一、Camera2 操作android.hardware.Camera 分析
- A Tutorial on android.hardware.camera2.*
- 使用android.hardware.camera2打造新的自定义相机
- cts android.hardware.camera2.cts.RecordingTest --testBasicRecording fail
- android.hardware.camera2详解(实时更新,未完待续...)
- android camera2
- Android camera2
- android - hardware
- Android -- Camera2(Android5.0)
- Android 5.0 Camera2 介绍
- Android -- Camera2(Android5.0)
- How to correctly read data when using epoll_wait
- POJ2431优先队列
- Stereo Vision 常用网站
- 【python】'''用法
- Python 高级特性 : 生成器
- android.hardware.camera2使用指南
- string.valueof和string 的区别 遇到错误才记忆深刻
- 学习Redis多数据库
- 写xml布局的时候 用adt看不了视图的时候,提示adt更新什么的。注意要看targetSdkVersion的值跟当前adt的版本是否相同
- php 编译安装phalcon组件遇到的坑
- QT5+OpenCV人脸识别
- scala线程demo-callable
- 使用openssl就算文件的MD5和SHA1值
- 信号_关于傅里叶变换