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