surfaceView +camera2 实现拍照功能

CSDN下载:https://download.csdn.net/download/qq_29099209/10288969

码云下载:


1、camera2流程示意图


Google采用了pipeline管道:将一件需要重复做的事情切割成各个不同的阶段,每一个阶段由独立的单元负责。所有待执行的对象依次进入作业队列)的概念,将CameraDevice相机设备和Android Device安卓设备连接起来, Android Device通过管道发送CaptureRequest拍照请求给Camera DeviceCameraDevice通过管道返回CameraMetadata数据给Android Device,这一切建立在一个叫作CameraCaptureSession的会话中。

2、Camera v2主要涉及的API:


Ø CameraManager:摄像头管理器。这是一个全新的系统管理器,专门用于检测系统摄像头、打开系统摄像头。除此之外,调用CameraManagergetCameraCharacteristics(String)方法即可获取指定摄像头的相关特性。

Ø CameraCharacteristics:摄像头特性。该对象通过CameraManager来获取,用于描述特定摄像头所支持的各种特性。

Ø CameraDevice:代表系统摄像头。该类的功能类似于早期的Camera类。

Ø CameraCaptureSession:这是一个非常重要的API,当程序需要预览、拍照时,都需要先通过该类的实例创建Session。而且不管预览还是拍照,也都是由该对象的方法进行控制的,其中控制预览的方法为setRepeatingRequest();控制拍照的方法为capture()

3、拍照步骤

Ø调用CameraManageropenCamera(StringcameraId, CameraDevice.StateCallback callback, Handler handler)方法打开指定摄像头。

该方法的第一个参数代表要打开的摄像头ID;第二个参数用于监听摄像头的状态;第三个参数代表执行callbackHandler,如果程序希望直接在当前线程中执行callback,则可将handler参数设为null。当摄像头被打开之后,程序即可获取CameraDevice—即根据摄像头ID获取了指定摄像头设备.

private CameraManager mCameraManager;

private int mCameraID;
public final int BACK_CAMERA = 0; //后置摄像头的CameraId,默认的mCameraID
mCameraID = BACK_CAMERA;//后摄像头
/**
 * 摄像头创建监听,获得摄像头状态stateCallback
 */
private CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    @Override
    public void onOpened(CameraDevice camera) {//打开摄像头
        mCameraDevice = camera;
        //开启预览
        takePreview();
    }

    @Override
    public void onDisconnected(CameraDevice camera) {//关闭摄像头
        if (null != mCameraDevice) {
            mCameraDevice.close();
            MainActivity.this.mCameraDevice = null;
        }
    }

    @Override
    public void onError(CameraDevice camera, int error) {//发生错误
        Toast.makeText(MainActivity.this, "摄像头开启失败", Toast.LENGTH_SHORT).show();
    }
};
//获取摄像头管理
mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
//打开摄像头
mCameraManager.openCamera(mCameraID + "", stateCallback, mainHandler);

Ø然后调用CameraDevicecreateCaptureSession(List<Surface>outputs,CameraCaptureSession.StateCallback callbackHandler handler)方法来创建CameraCaptureSession。该方法的第一个参数是一个List集合,封装了所有需要从该摄像头获取图片的Surface,第二个参数用于监听CameraCaptureSession的创建过程;第三个参数代表执行callbackHandler,如果程序希望直接在当前线程中执行callback,则可将handler参数设为null

 

预览图片:

 
// 创建预览需要的CaptureRequest.Builder
mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
// 将SurfaceView的surface作为CaptureRequest.Builder的目标
mPreviewRequestBuilder.addTarget(mSurfaceHolder.getSurface());
// 创建CameraCaptureSession,该对象负责管理处理预览请求和拍照请求
mCameraDevice.createCaptureSession(Arrays.asList(mSurfaceHolder.getSurface(), mImageReader.getSurface()), new CameraCaptureSession.StateCallback() {
    @Override
    public void onConfigured(CameraCaptureSession cameraCaptureSession) {
        if (null == mCameraDevice) return;
        // 当摄像头已经准备好时,开始显示预览
        mCameraCaptureSession = cameraCaptureSession;
        try {
            // 自动对焦
            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
            // 打开闪光灯
            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.FLASH_MODE_OFF);
            // 显示预览
            CaptureRequest previewRequest = mPreviewRequestBuilder.build();
            mCameraCaptureSession.setRepeatingRequest(previewRequest, null, childHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
        Toast.makeText(MainActivity.this, "配置失败", Toast.LENGTH_SHORT).show();
    }
}, childHandler);


 

点击拍照:

 
captureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
// 将imageReader的surface作为CaptureRequest.Builder的目标
captureRequestBuilder.addTarget(mImageReader.getSurface());
// 自动对焦
captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
// 自动曝光
captureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
// 获取手机方向
int rotation = getWindowManager().getDefaultDisplay().getRotation();
// 根据设备方向计算设置照片的方向
captureRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));
//拍照
CaptureRequest mCaptureRequest = captureRequestBuilder.build();
mCameraCaptureSession.capture(mCaptureRequest, null, childHandler);



不管预览还是拍照,程序都调用CameraDevicecreateCaptureRequest(int templateType)方法创建CaptureRequest.Builder,该方法支持TEMPLATE_PREVIEW(预览)、TEMPLATE_RECORD(拍摄视频)、TEMPLATE_STILL_CAPTURE(拍照)等参数。

通过第3步所调用方法返回的CaptureRequest.Builder设置拍照的各种参数,比如对焦模式、曝光模式等。

调用CaptureRequest.Builderbuild()方法即可得到CaptureRequest对象,接下来程序可通过CameraCaptureSessionsetRepeatingRequest()方法开始预览,或调用capture()方法拍照。







评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值