Camera2相机拍照流程之拍照功能梳理

/**
 * 拍照时调用方法
 */
private void captureStillPicture() {
    try {
        if (mCameraDevice == null) {
            return;
        }
        // 创建作为拍照的CaptureRequest.Builder
        mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
        // 将imageReader的surface作为CaptureRequest.Builder的目标
        mPreviewRequestBuilder.addTarget(mImageReader.getSurface());
		/*  // 设置自动对焦模式
        mBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
        // 设置自动曝光模式
        mBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);*/
        //设置为自动模式
		//mPreviewRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);

        setFlashMode(CONTROL_AE_MODE);
        // 停止连续取景
        mCaptureSession.stopRepeating();
        // 捕获静态图像
        mCaptureSession.capture(mPreviewRequestBuilder.build(), new CameraCaptureSession.CaptureCallback() {
            // 拍照完成时激发该方法
            @Override
            public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
                //重新打开预览
                createCameraPreview();
            }
        }, null);
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}

拍照流程如下:

1、通过cameraDevice对象创建拍照请求构建器对象mPreviewRequestBuilder。传入的CameraDevice.TEMPLATE_STILL_CAPTURE代表当前发送的请求是要准备拍照了。

// 创建作为拍照的CaptureRequest.Builder
mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);

2、通过mPreviewRequestBuilder设置照片数据输出到目标位置,即Surface。注意这个Surface在创建ImageReader对象的构造器时自动生成了;

mSurface = nativeGetSurface();

3、通过captueSession调用capture()函数发送一次捕获请求,这里也需要传入捕获状态回调对象,当拍照完成后会回调到onCaptureCompleted()函数,在这个函数中重新开启预览;

mCaptureSession.capture(mPreviewRequestBuilder.build(), new CameraCaptureSession.CaptureCallback()...)

4、捕获到的image数据读取并保存到本地图片文件中的过程其实是在mageReader.OnImageAvailableListener中的onImageAvailable()回调函数中完成的

/**
 * 预览请求构建器, 用来构建"预览请求"(下面定义的)通过pipeline发送到Camera device
 * 这是{@link ImageReader}的回调对象。 当静止图像准备保存时,将会调用“onImageAvailable”。
 */
private final ImageReader.OnImageAvailableListener mOnImageAvailableListener
        = new ImageReader.OnImageAvailableListener() {

    @Override
    public void onImageAvailable(ImageReader reader) {
        mFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + ".jpg");
        mBackgroundHandler.post(new ImageSaver(reader.acquireNextImage(), mFile));
    }

};

5、当完成照片的读取后,会对调到onCaptureCompleted()函数。

        只有执行capture()方法后才会回调到ImageAvailableListener的onImageAvailable函数。

onImageAvailable函数中的处理逻辑是:

1、创建一个本地文件对象;

2、通过handler对象发生一个消息到子线程中进程image数据流的读写;其中使用reader.acquireNextImage()获取到一帧图像数据。

3、具体读写操作在ImageSaver对象中,这里就是普通的文件读写了。

@Override
public void run() {
    ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();
    byte[] bytes = new byte[buffer.remaining()];
    buffer.get(bytes);
    FileOutputStream output = null;
    try {
        output = new FileOutputStream(mFile);
        output.write(bytes);
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        mImage.close();
        if (null != output) {
            try {
                output.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值