RAW support inside Full2PictureRecorder

pull/691/head
Mattia Iavarone 6 years ago
parent 0e2913a23b
commit 6df8ad2cb2
  1. 67
      cameraview/src/main/java/com/otaliastudios/cameraview/picture/Full2PictureRecorder.java

@ -3,12 +3,15 @@ package com.otaliastudios.cameraview.picture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.DngCreator;
import android.hardware.camera2.TotalCaptureResult;
import android.media.Image;
import android.media.ImageReader;
import android.os.Build;
import com.otaliastudios.cameraview.CameraLogger;
import com.otaliastudios.cameraview.PictureResult;
import com.otaliastudios.cameraview.controls.PictureFormat;
import com.otaliastudios.cameraview.engine.Camera2Engine;
import com.otaliastudios.cameraview.engine.action.Action;
import com.otaliastudios.cameraview.engine.action.ActionHolder;
@ -16,8 +19,11 @@ import com.otaliastudios.cameraview.engine.action.BaseAction;
import com.otaliastudios.cameraview.internal.utils.ExifHelper;
import com.otaliastudios.cameraview.internal.utils.WorkerHandler;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import androidx.annotation.NonNull;
@ -39,6 +45,8 @@ public class Full2PictureRecorder extends PictureRecorder
private final ImageReader mPictureReader;
private final CaptureRequest.Builder mPictureBuilder;
private DngCreator mDngCreator;
public Full2PictureRecorder(@NonNull PictureResult.Stub stub,
@NonNull Camera2Engine engine,
@NonNull CaptureRequest.Builder pictureBuilder,
@ -54,7 +62,9 @@ public class Full2PictureRecorder extends PictureRecorder
protected void onStart(@NonNull ActionHolder holder) {
super.onStart(holder);
mPictureBuilder.addTarget(mPictureReader.getSurface());
mPictureBuilder.set(CaptureRequest.JPEG_ORIENTATION, mResult.rotation);
if (mResult.format == PictureFormat.JPEG) {
mPictureBuilder.set(CaptureRequest.JPEG_ORIENTATION, mResult.rotation);
}
mPictureBuilder.setTag(CameraDevice.TEMPLATE_STILL_CAPTURE);
try {
holder.applyBuilder(this, mPictureBuilder);
@ -75,6 +85,20 @@ public class Full2PictureRecorder extends PictureRecorder
setState(STATE_COMPLETED);
}
}
@Override
public void onCaptureCompleted(@NonNull ActionHolder holder,
@NonNull CaptureRequest request,
@NonNull TotalCaptureResult result) {
super.onCaptureCompleted(holder, request, result);
if (mResult.format == PictureFormat.DNG) {
mDngCreator = new DngCreator(holder.getCharacteristics(this), result);
mDngCreator.setOrientation(mResult.rotation);
if (mResult.location != null) {
mDngCreator.setLocation(mResult.location);
}
}
}
};
}
@ -86,24 +110,37 @@ public class Full2PictureRecorder extends PictureRecorder
@Override
public void onImageAvailable(ImageReader reader) {
LOG.i("onImageAvailable started.");
// Read the JPEG.
Image image = null;
//noinspection TryFinallyCanBeTryWithResources
try {
image = reader.acquireNextImage();
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
mResult.data = bytes;
switch (mResult.format) {
case JPEG: readJpegImage(image); break;
case DNG: readRawImage(image); break;
default: throw new IllegalStateException("Unknown format: " + mResult.format);
}
} catch (Exception e) {
mResult = null;
mError = e;
dispatchResult();
return;
} finally {
if (image != null) image.close();
if (image != null) {
image.close();
}
}
// Leave.
LOG.i("onImageAvailable ended.");
dispatchResult();
}
private void readJpegImage(@NonNull Image image) {
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
mResult.data = bytes;
// Just like Camera1, unfortunately, the camera might rotate the image
// and put EXIF=0 instead of respecting our EXIF and leave the image unaltered.
mResult.rotation = 0;
@ -113,9 +150,19 @@ public class Full2PictureRecorder extends PictureRecorder
ExifInterface.ORIENTATION_NORMAL);
mResult.rotation = ExifHelper.readExifOrientation(exifOrientation);
} catch (IOException ignore) { }
}
// Leave.
LOG.i("onImageAvailable ended.");
dispatchResult();
private void readRawImage(@NonNull Image image) {
ByteArrayOutputStream array = new ByteArrayOutputStream();
BufferedOutputStream stream = new BufferedOutputStream(array);
try {
mDngCreator.writeImage(stream, image);
stream.flush();
mResult.data = array.toByteArray();
} catch (IOException e) {
mDngCreator.close();
try { stream.close(); } catch (IOException ignore) {}
throw new RuntimeException(e);
}
}
}

Loading…
Cancel
Save