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?
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);
}
-
3it freezes the Textureview. (mPreviewRequestBuilder.addTarget(mImageReader.getSurface());) – user1154390 Dec 19 '15 at 12:54
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.

- 17,243
- 2
- 42
- 47
-
@ Eddy Talvala, When I add target like mPreviewRequestBuilder.addTarget(mImageReader.getSurface()); It freezes the surfaces. – user1154390 Dec 19 '15 at 14:20
-
What error do you get in the logcat? And did you add the surface to your createCaptureSession call? – Eddy Talvala Dec 20 '15 at 18:34
-
Yes set both surfaces for output in createCaptureSession. Logcat doesn't show any Error. It lock straight forward but stuck from last two day. – user1154390 Dec 20 '15 at 18:55
-
logcat :- Time out while waiting for request to complete. It sends only three requests to ImageReader Callback. – user1154390 Dec 20 '15 at 19:11
-
Are you calling image.close() after being done with each Image? If not, you'll starve the camera for free buffers. – Eddy Talvala Dec 21 '15 at 19:25
-
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. – user1154390 Dec 22 '15 at 10:08