Android CameraApi2 / CameraX Image to ByteBuffer converter.
7 years passed since CameraApi 2 was introduced in Android 5. So Google decided that it's time to make convenient way to get RGB images from it.
ImageAnalysis from CaemraX now supports setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_RGBA_8888) developer.android.com
Hovewer if you do not use CameraX for some reason - welcome!
Motivation:
When you're attempting to get an Image
from ImageReader
or ImageAnalysis.Analyzer
you actually get 3 separate ByteBuffers
which you can't pass to further processing. You have to merge them but that also is not easy because they are full of row and pixel strides.
Solution:
This library carefully merges 3 buffers into one with respect to all strides. As a result, you receive YUV type (NV21
or I420
) and ByteBuffer
to pass into OpenCV or a neural network framework.
The solution was tested with CameraX, CameraApi 2, and MediaCodec (for video files).
The whole library is a single file, you can just copy Yuv.java into your project.
Usage
private var reuseBuffer: ByteBuffer? = null
fun convert(image: ImageProxy): Pair<Bitmap, Long> {
// val converted = Yuv.toBuffer(image)
// OR pass existing DirectBuffer for reuse
val converted = Yuv.toBuffer(image, reuseBuffer)
reuseBuffer = converted.buffer
val format = when (converted.type) {
ImageFormat.YUV_420_888 -> Imgproc.COLOR_YUV2RGB_I420
ImageFormat.NV21 -> Imgproc.COLOR_YUV2RGB_NV21
else -> throw IllegalArgumentException()
}
// process converted.buffer ByteBuffer with one of converters
}
About android image formats
In android documentation ImageFormat.YUV_420_888 is stated as 'generic YCbCr format', so the actual format depends on u and v order and are these planes interleaved or not (pixelStride=1 or 2).
Most of the time you will get NV21 format (just as in Camera1 api).
And you even may start wondering is there a phone with I420 format (u and v pixelStride==1) – Yes! There is one. Blackview BV6000S Android 7.0. Screenshot. It looks like it's the only one. Other models of Blackview I was able to find in local sellers used NV21.
Converters
PS: If your goal is to get Mat you may consider this method from OpenCV.
Benchmark
Snapdragon 855 (Xiaomi Mi 9T Pro). Image resolution 480x640.
OpenCV (YUV rotate) | OpenCV (RGB rotate) | RenderScript | MNN | |
---|---|---|---|---|
color | ~1ms | ~1.6ms | ~2.2ms | ~21ms |
rotate | ~3.5ms | ~2.8ms | ~16.3ms | NA (included in color) |
Alternatives