I've been working on a simple Android app designed to pass streaming camera frames from the Android Camera2 API pipeline to my algorithm. I've made several applications already that faithfully do this using the Android Camera1 API, but even after checking (Google docs, forums) to confirm correct coding, I am unable to capture any real data from the ImageReader in onImageAvailable(). Please note the following relevant code:
Setting up the ImageReaders:
private void setUpCameraOutputs(int width, int height) {
[....code....]
mImageReader = ImageReader.newInstance(smallestJPEG.getWidth(),
smallestJPEG.getHeight(),
ImageFormat.JPEG, /*maxImages*/2);
// mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, null);
mPreviewImageReader = ImageReader.newInstance(smallest.getWidth(),
smallest.getHeight(),
ImageFormat.YUV_420_888, 2);
mPreviewImageReader.setOnImageAvailableListener(mOnPreviewImageAvailableListener,
mBackgroundHandler);
[....code....]
}
Setting up the CaptureSession:
private void createCameraPreviewSession() {
try {
//Create Texture from Screen's TextureView
SurfaceTexture texture = mTextureView.getSurfaceTexture();
assert texture != null;
//Configure Default Buffer Size
texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
//Create Output Surface from Texture
Surface surface = new Surface(texture);
// Set up a CaptureRequest.Builder with the output Surface.
mPreviewRequestBuilder
= mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
//Add Output Display surface
mPreviewRequestBuilder.addTarget(surface);
//Add Preview frame-grabbing surface
mPreviewRequestBuilder.addTarget(mPreviewImageReader.getSurface());
mCameraDevice.createCaptureSession(Arrays.asList(surface, mPreviewImageReader.getSurface()),
new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession cameraCaptureSession) {
// The camera is already closed
if (null == mCameraDevice) {
return;
}
// When the session is ready, we start displaying the preview.
mCaptureSession = cameraCaptureSession;
try {
// Auto focus should be continuous for camera preview. [...code...]
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
// Flash is automatically enabled when necessary.
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
// Finally, we start displaying the camera preview.
mPreviewRequest = mPreviewRequestBuilder.build();
mCaptureSession.setRepeatingRequest(mPreviewRequest,
mCaptureCallback, mBackgroundHandler);
} catch (CameraAccessException e) {
[...code...]
}
}
@Override
public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
[...code...]
}
}, null
);
} catch (CameraAccessException e) {
[...code...]
}
}
Setting up the OnImageAvailableListener:
private ImageReader mPreviewImageReader;
private final ImageReader.OnImageAvailableListener mOnPreviewImageAvailableListener
= new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
//Acquire Image, ByteBuffer, then byte array
Image image = reader.acquireLatestImage();
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.remaining()];
//Check bytes array for anydata
int cnt = 0;
for (int i = 0; i < bytes.length; i++){
if (bytes[i] != 0)cnt++;
}
Log.i(TAG, "cnt = " + cnt);
image.close();
//At this point, byte[] bytes is empty (all zero)
[...code...]
}
};
In code snippet #3, my byte buffer always returns empty (all zeros), regardless of ImageReader format. Has anyone had this issue? Am I missing any code?
add buffer.get(bytes); after byte[] bytes = new byte[buffer.remaining()];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With