Search code examples
androidandroid-cameraandroid-camera2

How do I choose an ImageReader buffer type for my Android camera app?


I have an app with a camera function. I'm using the Android Camera2 API. I've found that some Android devices (e.g. Nexus 6p, Nexus 5) work better if the ImageReader is configured to provide JPEGs:

imageReader = ImageReader.NewInstance(width, height, ImageFormatType.Jpeg, 2);

And some Android devices (e.g. Nexus 7 2013) work better if the ImageReader is configured to provide, say, RGBA_8888:

imageReader = ImageReader.NewInstance(width, height, (ImageFormatType)1 /* PixelFormat.RGBA_8888 */, 2);

The device that works better with JPEGs spits out this error if I use RGBA_8888:

[ImageReader_JNI] Producer output buffer format: 0x22, ImageReader configured format: 0x1

The device that works better with RGBA buffers spits out this warning if I use JPEGs: (It still works, but it's slow enough that the captured picture is dark.)

[ImageReader_JNI] ImageReader_lockedImageSetup: Receiving JPEG in HAL_PIXEL_FORMAT_RGBA_8888 buffer.

I have to do some processing on what I get back, so ultimately it would be better if I could configure the camera to just spit out some sort of bitmap rather than a JPEG, since I have to convert the JPEG to a Bitmap before continuing.

How should I choose what buffer type to pass to the ImageReader?


Solution

  • The only guaranteed formats that all camera devices must support are YUV_420_888 and JPEG; even at that, LEGACY-level devices generally only support JPEG at maximum resolution (and YUV_420_888 at preview resolutions, not generally higher than 1080p).

    You should be checking the list of supported formats in the device's StreamConfigurationMap instead of just blindly trying some - while some devices may support random formats not listed in their official list, there's not much guarantee about how well they'll do so.

    JPEG capture tends to be slower because LEGACY-level devices assume that when you want a JPEG, you want maximum still capture quality, which takes more post-processing than just a preview frame; plus, LEGACY devices may do flash metering and firing. LIMITED or better devices allow you to control the post-processing quality, so it's not tied to the output format, and also generally support higher resolutions of YUV capture.

    I'd generally stay away from RGBA if you want wide support - it working with LEGACY devices is a bit of a quirk, and LIMITED and better devices are unlikely to support it.

    When you say that JPEG works, but is slow enough that the captured image is dark, I'm a bit confused - why does slowness mean a dark image? Or do you just mean the images come out dark?