Skip to content
This repository has been archived by the owner on Dec 29, 2022. It is now read-only.

Added preview callback #123

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions library/src/main/api14/com/google/android/cameraview/Camera1.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,17 @@ void setUpPreview() {
} else {
mCamera.setPreviewTexture((SurfaceTexture) mPreview.getSurfaceTexture());
}

mCamera.setPreviewCallback(new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
final Camera.Parameters parameters = camera.getParameters();
final int width = parameters.getPreviewSize().width;
final int height = parameters.getPreviewSize().height;
mCallback.onPreviewFrame(data, parameters.getPreviewFormat(), width, height);
}
});

} catch (IOException e) {
throw new RuntimeException(e);
}
Expand Down
78 changes: 67 additions & 11 deletions library/src/main/api21/com/google/android/cameraview/Camera2.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import android.media.Image;
import android.media.ImageReader;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.util.SparseIntArray;
import android.view.Surface;
Expand Down Expand Up @@ -156,19 +157,26 @@ public void onReady() {

@Override
public void onImageAvailable(ImageReader reader) {
try (Image image = reader.acquireNextImage()) {
Image.Plane[] planes = image.getPlanes();
if (planes.length > 0) {
ByteBuffer buffer = planes[0].getBuffer();
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
mCallback.onPictureTaken(data);
}
byte[] data = getByteDataFromImageReader(reader);
if (data != null) {
mCallback.onPictureTaken(data);
}
}

};

private final ImageReader.OnImageAvailableListener mOnPreviewImageAvailableListener
= new ImageReader.OnImageAvailableListener() {

@Override
public void onImageAvailable(ImageReader reader) {
byte[] data = getByteDataFromImageReader(reader);
if (data != null) {
mCallback.onPreviewFrame(data, reader.getImageFormat(),
reader.getWidth(),
reader.getHeight());
}
}
};

private String mCameraId;

Expand All @@ -182,6 +190,8 @@ public void onImageAvailable(ImageReader reader) {

private ImageReader mImageReader;

private ImageReader mCallbackImageDataReader;

private final SizeMap mPreviewSizes = new SizeMap();

private final SizeMap mPictureSizes = new SizeMap();
Expand Down Expand Up @@ -232,6 +242,11 @@ void stop() {
mImageReader.close();
mImageReader = null;
}

if (mCallbackImageDataReader != null) {
mCallbackImageDataReader.close();
mCallbackImageDataReader = null;
}
}

@Override
Expand Down Expand Up @@ -435,11 +450,49 @@ protected void collectPictureSizes(SizeMap sizes, StreamConfigurationMap map) {

private void prepareImageReader() {
Size largest = mPictureSizes.sizes(mAspectRatio).last();
mImageReader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(),
initImageReader(largest.getWidth(), largest.getHeight());

Size size = chooseOptimalSize();
initCallbackImageDataReader(size.getWidth(), size.getHeight());
}

private void initImageReader(int width, int height){
mImageReader = ImageReader.newInstance(width, height,
ImageFormat.JPEG, /* maxImages */ 2);
mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, null);
}

private void initCallbackImageDataReader(int width, int height) {

if (mCallbackImageDataReader != null) {
mCallbackImageDataReader.close();
}

mCallbackImageDataReader = ImageReader.newInstance(width, height,
ImageFormat.NV21, /* maxImages */ 1);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, I don't think NV21 is supported in Camera2. It should be YUV_420_888 in Camera2 case. It cashed on my N5X with Caused by: java.lang.IllegalArgumentException: NV21 format is not supported

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mCallbackImageDataReader.setOnImageAvailableListener(mOnPreviewImageAvailableListener, null);
}

/**
* Extract the byte data from the ImageReader
* @param reader
* @return byte array or null if failed
*/
@Nullable
private byte[] getByteDataFromImageReader(@NonNull ImageReader reader) {
byte[] data = null;
try (Image image = reader.acquireNextImage()) {
Image.Plane[] planes = image.getPlanes();
if (planes.length > 0) {
ByteBuffer buffer = planes[0].getBuffer();
data = new byte[buffer.remaining()];
buffer.get(data);
}
}
return data;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some image formats have multiple planes, including YUV420_888 (the default for Camera2). All planes need to be included in the output byte array.


/**
* <p>Starts opening a camera device.</p>
* <p>The result will be processed in {@link #mCameraDeviceCallback}.</p>
Expand All @@ -463,11 +516,14 @@ void startCaptureSession() {
}
Size previewSize = chooseOptimalSize();
mPreview.setBufferSize(previewSize.getWidth(), previewSize.getHeight());

Surface surface = mPreview.getSurface();
try {
mPreviewRequestBuilder = mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
mPreviewRequestBuilder.addTarget(surface);
mCamera.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()),
mPreviewRequestBuilder.addTarget(mCallbackImageDataReader.getSurface());
mCamera.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface(),
mCallbackImageDataReader.getSurface()),
mSessionCallback, null);
} catch (CameraAccessException e) {
throw new RuntimeException("Failed to start camera session");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ interface Callback {

void onPictureTaken(byte[] data);

void onPreviewFrame(byte[] data, int format, int width, int height);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,13 @@ public void onPictureTaken(byte[] data) {
}
}

@Override
public void onPreviewFrame(byte[] data, int format, int width, int height) {
for (Callback callback : mCallbacks) {
callback.onPreviewFrame(data, format, width, height);
}
}

public void reserveRequestLayoutOnOpen() {
mRequestLayoutOnOpen = true;
}
Expand Down Expand Up @@ -534,6 +541,17 @@ public void onCameraClosed(CameraView cameraView) {
*/
public void onPictureTaken(CameraView cameraView, byte[] data) {
}

/**
* Called when a preview frame is rendered
* @param data raw byte data
* @param format data format
* @param width image width
* @param height image height
*/
public void onPreviewFrame(byte[] data, int format, int width, int height){
}

}

}