1.Camera2
Android API 21新增了Camera2,与之前的Camera架构完全不同,使用起来也比较复杂,但是功能变得很强大。
Camera2中几个比较重要的类:
①CameraManager: 管理手机上的所有摄像头设备。它其实是一个系统服务,通过getSystemService(Context.CAMERA_SERVICE)获取,它的作用主要是获取摄像头列表和打开指定的摄像头。
通过CameraManager对象可以得到一些相机的基本信息,这个信息就存储在CameraCharacteristic对象中。获取到相机的一些基本信息:
CameraCharacteristics cameraInfo = mCameraManager.getCameraCharacteristics(cameraId);
除了获取Camera的属性信息外,CameraManager对象最重要的作用就是打开相机(openCamera),通过CameraManager才能真正的拿到CameraDevice对象去操作相机:
mCameraManager.openCamera(cameraId, mCameraDeviceStateCallback, null);
cameraId:需要打开的摄像头的id
mCameraDeviceStateCallback:一个CameraDevice的状态回调类,在这个类回调方法里,会告知Camera设备的打开状态,成功还是失败
Handler:openCamera的操作在哪个线程执行,null即为在主线程执行
②CameraDevice:表示一个打开的相机设备,在CameraDevice.StateCallback的onOpened回调里返回此实例对象。它的作用主要是创建CameraCaptureSession和CaptureRequest。
有了CameraDevice对象,就可以创建上层与Camera设备之间的一个会话,在Camera2中即为CameraCaptureSession:
mCameraDevice.createCaptureSession(Arrays.asList(mPreviewSurface,mImagerReader.getSurface()),mCaptureSessionStateCallback,null);
第一个参数List<Surface> outputs:Arrays.asList( mPreviewSurface,mMediaRecorder.getSurface()):代表要配置的流的数量(这里是一个预览流和拍照流)。
第二个参数mCaptureSessionStateCallback:CameraCaptureSession创建的对象的状态回调
第三个参数Handler:createCaptureSession的操作在哪个线程执行,null即为在主线程执行
③CameraCaptureSession: 相机捕获会话,代表上层与底层之间的一个会话,通过这个会话可以下发指令给相机,让相机执行预览、拍照录像等操作,在mCameraDevice.createCaptureSession的回调中获得。主要作用是用于处理拍照和预览的工作(很重要)。
想从相机设备中获取Image,首先要创建一个CameraCaptureSession把接收数据的载体传给相机设备,目前能接收相机数据的载体是Surface和SurfaceTexture。
通过情况下,相机的预览数据可以使用SurfaceView和TextureView接收。拍照使用ImageReader、录视频使用MediaCodec或MediaRecorder。
④CaptureRequest和CaptureResult
CaptureRequest代表相机捕获请求,当CaptureCaptureSession创建好之后,就可以使用这个会话来下发指令,表明当前是需要预览、拍照、还是录像。CaptureRequest对象可以携带设置的参数,比如是否自动对焦、自动曝光、自动白平衡等。CaptureRequest对象的创建使用了建造者模式,需要通过CaptureRequest.Builder来创建,通过调用build方法:
PreviewRequest = mCaptureRequestBuilder.build();
mCaptureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);//自动连续对焦
mCaptureRequestBuilder.addTarget(mPreviewSurface); //预览流,底层回来的数据放在哪里
mCaptureRequestBuilder.addTarget(mImageReader.getSurface());拍照流
PreviewRequest = mCaptureRequestBuilder.build();
//这里是下发预览,如果是拍照可以调用capture()方法
mCameraCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureSessionCaptureCallback, null);
CaptureRequest定义了输出缓冲区以及显示界面(TextureView或SurfaceView)等。
CaptureResut代表捕获请求返回的一些结果信息,从里面可以获取一些Metadata数据信息。
2.Camera2实现预览和拍照
使用Camera2进行预览和拍照的主要流程: