Reading RGB images with an ImageReader

2020-05-23 01:17发布

问题:

I'm trying to use an ImageReader to get RGB images from the camera. I'm using the Camera2 API from Android 5.0 "L" on a Nexus 5 running the developer preview.

I already have a SurfaceView configured for RGB images which is working fine, and I know that the camera hardware produces RGB data (because all the tone mapping and color gain settings on Android are specified to operate on RGB channels).

I can obtain YUV_420_888 images from ImageReader by creating the ImageReader this way:

imageReader = ImageReader.newInstance(W, H, ImageFormat.YUV_420_888, 4);

and then converting the YUV images to RGB. However, this is introducing both an unwanted quantization error (since my application requires RGB images), and unnecessary processing time.

However, when I try creating the image reader this way:

imageReader = ImageReader.newInstance(W, H, PixelFormat.RGB_888, 4);

the image capture fails with the following exception:

java.lang.UnsupportedOperationException: The producer output buffer format 0x22 doesn't match the ImageReader's configured buffer format 0x3.
        at android.media.ImageReader.nativeImageSetup(Native Method)
        at android.media.ImageReader.acquireNextSurfaceImage(ImageReader.java:293)
        at android.media.ImageReader.acquireNextImage(ImageReader.java:339)
        at android.media.ImageReader.acquireLatestImage(ImageReader.java:243)
        at <my code...>

I'm confused on two fronts. First, the output format mentioned, 0x22, is not in either PixelFormat or ImageFormat. It seems to be some sort of undocumented raw mode, but I can't use ImageReader.newInstance(W, H, 0x22, 4) to capture it (I get java.lang.UnsupportedOperationException: Invalid format specified 34). I would love to capture in the raw format but I can't convince ImageFormat to accept it (and the other raw format ImageFormat.RAW_SENSOR is incredibly slow for some reason).

Second, the SurfaceView is already happily consuming RGB_888 images (as far as I can tell), and putting them directly on the screen. So why isn't ImageReader not accepting RGB images properly? What did I do wrong?