Camera.PreviewCallback equivalent in Camera2 API
Asked Answered
U

2

21

Is there any equivalent for Camera.PreviewCallback in Camera2 from API 21,better than mapping to a SurfaceTexture and pulling a Bitmap ? I need to be able to pull preview data off of the camera as YUV?

Unlikely answered 10/2, 2015 at 19:54 Comment(0)
V
17

You can start from the Camera2Basic sample code from Google.

You need to add the surface of the ImageReader as a target to the preview capture request:

//set up a CaptureRequest.Builder with the output Surface
mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
mPreviewRequestBuilder.addTarget(surface);
mPreviewRequestBuilder.addTarget(mImageReader.getSurface());

After that, you can retrieve the image in the ImageReader.OnImageAvailableListener:

private final ImageReader.OnImageAvailableListener mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() {
    @Override
    public void onImageAvailable(ImageReader reader) {
        Image image = null;
        try {
            image = reader.acquireLatestImage();
            if (image != null) {
                ByteBuffer buffer = image.getPlanes()[0].getBuffer();
                Bitmap bitmap = fromByteBuffer(buffer);
                image.close();
            }
        } catch (Exception e) {
            Log.w(LOG_TAG, e.getMessage());
        }
    }
};

To get a Bitmap from the ByteBuffer:

Bitmap fromByteBuffer(ByteBuffer buffer) {
    byte[] bytes = new byte[buffer.capacity()];
    buffer.get(bytes, 0, bytes.length);
    return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
}
Veliz answered 21/10, 2015 at 20:17 Comment(1)
it freezes the Textureview. (mPreviewRequestBuilder.addTarget(mImageReader.getSurface());)Oyez
N
7

Yes, use the ImageReader class.

Create an ImageReader using the format ImageFormat.YUV_420_888 and your desired size (make sure you select a size that's supported by the camera device you're using).

Then use ImageReader.getSurface() for a Surface to provide to CameraDevice.createCaptureSession(), along with your other preview outputs, if any.

Finally, in your repeating capture request, add the ImageReader provided surface as a target before setting it as the repeating request in your capture session.

Neither answered 20/2, 2015 at 22:39 Comment(6)
@ Eddy Talvala, When I add target like mPreviewRequestBuilder.addTarget(mImageReader.getSurface()); It freezes the surfaces.Oyez
What error do you get in the logcat? And did you add the surface to your createCaptureSession call?Neither
Yes set both surfaces for output in createCaptureSession. Logcat doesn't show any Error. It lock straight forward but stuck from last two day.Oyez
logcat :- Time out while waiting for request to complete. It sends only three requests to ImageReader Callback.Oyez
Are you calling image.close() after being done with each Image? If not, you'll starve the camera for free buffers.Neither
Thanks, I sorted out the problem. I was not consuming the Image reader on callback. I was just displaying a log to test callback run or not.Oyez

© 2022 - 2024 — McMap. All rights reserved.