Android Camera2 实现连拍

gitee 链接:
通过 captureBurst 实现连拍
拍完的图片放在 /data/data/com.example.burstcapture/files/
图片路径
连拍的具体实现代码在 BurstCapture.java 、BurstCaptureExpo.java、BurstCaptureFocus.java中,调用在 MainActivity.java中,调用方式很简单
连拍调用方式

普通连拍直接创建 BurstCapture 这个类,在这个类的构造方法中会发 request

注意 :下面代码中的照片保存的路径 /data/data/com.example.burstcapture/files/ 中的 files 文件夹是我自己创建的,你需要自己手动创建下。

下面代码即可实现连拍:

mImageReader.setOnImageAvailableListener(mReaderImgListener, null);
mStillBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
mStillBuilder.addTarget(mImageSurface);
CaptureRequest request = mStillBuilder.build();
List<CaptureRequest> requests = new ArrayList<>();
// 改变下面的i的取值范围就可以改变连拍的数量
for(int i=0;i<3;i++)
    requests.add(request);
mCaptureSession.captureBurst(requests, null, null);
ImageReader.OnImageAvailableListener mReaderImgListener = new ImageReader.OnImageAvailableListener() {
    @Override
    public void onImageAvailable(ImageReader reader) {
        writeImageToFile();
    }
};
private void writeImageToFile() {
    String filePath = "/data/data/com.example.burstcapture/files/"+imageIndex+".jpg";
    imageIndex++;
    Image image = mImageReader.acquireNextImage();
    if (image == null) {
        return;
    }
    ByteBuffer byteBuffer = image.getPlanes()[0].getBuffer();
    byte[] data = new byte[byteBuffer.remaining()];
    byteBuffer.get(data);
    FileOutputStream fos = null;
    try {
        fos = new FileOutputStream(new File(filePath));
        fos.write(data);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            fos.close();
            fos = null;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            image.close();
            image = null;
        }
    }
}

不同曝光时间的连拍:

mStillBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
mStillBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT, CaptureRequest.CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
// 把AE关掉,通过手动的方式控制AE
mStillBuilder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_OFF);
private void takePicturePrecapture(){
    final CaptureRequest.Builder precaptureBuilder;
    try {
        precaptureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
        precaptureBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT, CaptureRequest.CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
        precaptureBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_IDLE);
        precaptureBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CameraMetadata.CONTROL_AE_PRECAPTURE_TRIGGER_IDLE);
        precaptureBuilder.addTarget(mPreViewSurface);
        int sequenceId = mCaptureSession.capture(precaptureBuilder.build(), null, null);
        sequenceId = mCaptureSession.setRepeatingRequest(precaptureBuilder.build(), null, null);
        precaptureBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CameraMetadata.CONTROL_AE_PRECAPTURE_TRIGGER_START);

        sequenceId = mCaptureSession.capture(precaptureBuilder.build(), mMCaptureCallback, null);

    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}
MCaptureCallback mMCaptureCallback = new MCaptureCallback();
    private class  MCaptureCallback extends CameraCaptureSession.CaptureCallback {
        @Override
        public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
            Log.e("TAG", "============================== onCaptureCompleted: ");
            Integer ae_state = result.get(CaptureResult.CONTROL_AE_STATE);

            if (ae_state == CaptureResult.CONTROL_AE_STATE_PRECAPTURE){
                try {
                    mStillBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
                    mStillBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT, CaptureRequest.CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
                    // 把AE关掉,通过手动的方式控制AE
                    mStillBuilder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_OFF);
                    mStillBuilder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_TORCH); // just in case
                    mStillBuilder.addTarget(mImageSurface);
                    CaptureRequest captureRequest = mStillBuilder.build();
                    List<CaptureRequest> requests = new ArrayList<>();

                    Range<Integer> iso_range = mCharacteristics.get(CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE); // may be null on some devices
                    int iso = 800;
                    // see https://sourceforge.net/p/opencamera/tickets/321/ - some devices may have auto ISO that's
                    // outside of the allowed manual iso range!
                    iso = Math.max(iso, iso_range.getLower());
                    iso = Math.min(iso, iso_range.getUpper());
                    mStillBuilder.set(CaptureRequest.SENSOR_SENSITIVITY, iso );
                    mStillBuilder.set(CaptureRequest.SENSOR_FRAME_DURATION, 1000000000L/30);

                    int n_half_images = 3/2;
                    long base_exposure_time = 22222000;
                    long min_exposure_time = base_exposure_time;
                    long max_exposure_time = base_exposure_time;
                    float expo_bracketing_stops = 2.0f;
                    final double scale = Math.pow(2.0, expo_bracketing_stops/(double)n_half_images);
                    Range<Long> exposure_time_range = mCharacteristics.get(CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE); // may be null on some devices
                    if( exposure_time_range != null ) {
                        min_exposure_time = exposure_time_range.getLower();
                        max_exposure_time = exposure_time_range.getUpper();
                    }
                    // darker images
                    for(int i=0;i<1;i++) {
                        long exposure_time = base_exposure_time;
                        if( exposure_time_range != null ) {
                            double this_scale = scale;
                            for(int j=i;j<n_half_images-1;j++)
                                this_scale *= scale;
                            exposure_time /= this_scale;
                            if( exposure_time < min_exposure_time )
                                exposure_time = min_exposure_time;
                            mStillBuilder.setTag(new String("darker images"));
                            mStillBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, exposure_time);
                            Log.e("TAG", " 0000000000 ");
                            requests.add( mStillBuilder.build() );
                        }
                    }
                    Log.e("666666", "scale = "+scale +" base_exposure_time = "+base_exposure_time+" exposure_time = "+base_exposure_time/scale);

                    mStillBuilder.setTag(new String("base image"));
                    // base image
                    mStillBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, base_exposure_time);
                    requests.add( mStillBuilder.build() );

                    // lighter images
                    for(int i=0;i<n_half_images;i++) {
                        long exposure_time = base_exposure_time;
                        if( exposure_time_range != null ) {
                            double this_scale = scale;
                            for(int j=0;j<i;j++)
                                this_scale *= scale;
                            exposure_time *= this_scale;
                            if( exposure_time > max_exposure_time )
                                exposure_time = max_exposure_time;
                            mStillBuilder.setTag(new String("lighter images"));
                            mStillBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, exposure_time);
                            Log.e("TAG", " 1111111111111 ");
                            requests.add( mStillBuilder.build() );
                        }
                    }
                    Log.e("TAG", "n_half_images = "+n_half_images );
                    Log.e("666666", "scale = "+scale +" exposure_time = "+(scale * base_exposure_time)+" base_exposure_time = "+base_exposure_time);

//            mCaptureSession.stopRepeating();
                    mCaptureSession.captureBurst(requests, null, null);
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
            }
            super.onCaptureCompleted(session, request, result);
        }
    }
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 18
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值