Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Camera.PreviewCallback equivalent in Camera2 API

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?

like image 581
user3605225 Avatar asked Feb 10 '15 19:02

user3605225


People also ask

Is Camera2 API deprecated?

camera2 API for new applications. This interface was deprecated in API level 21. We recommend using the new android.

What is the use of camera 2 API?

Camera2 is the latest low-level Android camera package and replaces the deprecated Camera class. Camera2 provides in-depth controls for complex use cases, but requires you to manage device-specific configurations.

Is a camera a device?

A digital camera is a hardware device that takes photographs and stores the image as data on a memory card.


2 Answers

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);
}
like image 121
EmcLIFT Avatar answered Oct 24 '22 20:10

EmcLIFT


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.

like image 23
Eddy Talvala Avatar answered Oct 24 '22 22:10

Eddy Talvala