android.hardware.camera2使用指南
来源:互联网 发布:python apscheduler 编辑:程序博客网 时间:2024/05/16 18:35
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去显示,详见参考中的项目)
核心代码如下:
mCameraManager = (CameraManager) this.getSystemService(Context.CAMERA_SERVICE); mSurfaceView = (SurfaceView)findViewById(R.id.surfaceview); mSurfaceHolder = mSurfaceView.getHolder(); mSurfaceHolder.addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { initCameraAndPreview(); } });
private void initCameraAndPreview() { Log.d(linc,init camera and preview); HandlerThread handlerThread = new HandlerThread(Camera2); handlerThread.start(); mHandler = new Handler(handlerThread.getLooper()); try { mCameraId = +CameraCharacteristics.LENS_FACING_FRONT; mImageReader = ImageReader.newInstance(mSurfaceView.getWidth(), mSurfaceView.getHeight(), ImageFormat.JPEG,/*maxImages*/7); mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mHandler); mCameraManager.openCamera(mCameraId, DeviceStateCallback, mHandler); } catch (CameraAccessException e) { Log.e(linc, open camera failed. + e.getMessage()); } }
private CameraDevice.StateCallback DeviceStateCallback = new CameraDevice.StateCallback() { @Override public void onOpened(CameraDevice camera) { Log.d(linc,DeviceStateCallback:camera was opend.); mCameraOpenCloseLock.release(); mCameraDevice = camera; try { createCameraCaptureSession(); } catch (CameraAccessException e) { e.printStackTrace(); } } };
private void createCameraCaptureSession() throws CameraAccessException { Log.d(linc,createCameraCaptureSession); mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); mPreviewBuilder.addTarget(mSurfaceHolder.getSurface()); mState = STATE_PREVIEW; mCameraDevice.createCaptureSession( Arrays.asList(mSurfaceHolder.getSurface(), mImageReader.getSurface()), mSessionPreviewStateCallback, mHandler); }
private CameraCaptureSession.StateCallback mSessionPreviewStateCallback = new CameraCaptureSession.StateCallback() { @Override public void onConfigured(CameraCaptureSession session) { Log.d(linc,mSessionPreviewStateCallback onConfigured); mSession = session; try { mPreviewBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); mPreviewBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); session.setRepeatingRequest(mPreviewBuilder.build(), mSessionCaptureCallback, mHandler); } catch (CameraAccessException e) { e.printStackTrace(); Log.e(linc,set preview builder failed.+e.getMessage()); } } };
private CameraCaptureSession.CaptureCallback mSessionCaptureCallback = new CameraCaptureSession.CaptureCallback() { @Override public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {// Log.d(linc,mSessionCaptureCallback, onCaptureCompleted); mSession = session; checkState(result); } @Override public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request, CaptureResult partialResult) { Log.d(linc,mSessionCaptureCallback, onCaptureProgressed); mSession = session; checkState(partialResult); } private void checkState(CaptureResult result) { switch (mState) { case STATE_PREVIEW: // NOTHING break; case STATE_WAITING_CAPTURE: int afState = result.get(CaptureResult.CONTROL_AF_STATE); if (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) { //do something like save picture } break; } } };
按下capture按钮:
public void onCapture(View view) { try { Log.i(linc, take picture); mState = STATE_WAITING_CAPTURE; mSession.setRepeatingRequest(mPreviewBuilder.build(), mSessionCaptureCallback, mHandler); } catch (CameraAccessException e) { e.printStackTrace(); } }
测试用genemotion模拟器,直接调用笔记本的摄像头。
配置图如下:
demo界面如下图:
0 0
- 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)
- 关于“相同IP不同子网掩码”的疑惑
- 初识Activity
- 查找最大元素(HDU2025)
- Android 增强版百分比布局库 为了适配而扩展
- 汇编指令【下】
- android.hardware.camera2使用指南
- latex学习3:教你如何在word中像LaTex那样打公式
- jquery的html,text,val
- FZUOJ-2128 最长子串(strstr函数枚举暴力)
- 深入理解javascript原型和闭包系列 深入理解javascript原型和闭包(1)——一切都是对象
- XUtils net
- 树状数组
- android开发之SearchView
- 阅读STL源码剖析笔记 —— 迭代器概念