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);
}
}