I’m trying to access the raw pixel data of an image in Android.
The code looks something like this:
Bitmap bitmap = BitmapFactory.decodeFile("image.png");
// assert valid input
if ((bitmap.getConfig() == null) || bitmap.getConfig() == Config.ARGB_8888)
throw new Exception("bad config");
ByteBuffer buffer = ByteBuffer.allocate(4 * bitmap.getWidth() * bitmap.getHeight());
bitmap.copyPixelsToBuffer(buffer);
return buffer.array();
How are the pixels in the linear 1D buffer.array() stored?
- First element is top-left pixel or bottom-left pixel (or something else)?
- Row-major (row after row) or column-major (column after column)?
- Channel order ARGB or BGRA?
- Row-major or column-major for each channel separately?
- Something else
To get the offset into
buffer.array()for a given pixelx,yin an image of sizewidthxheightwithbytesPerPixelbytes per pixel, use this formula:In other words, the first element in the array is the top-left pixel, and the following elements are row-major. All data for a pixel are stored in adjacent bytes and are not spread out based on channel. This is the answer to 1, 2 and 4 above. Now let’s discuss 3, which is where things become complicated.
What you get with Bitmap.copyPixelsToBuffer() is the raw bitmap data representation used by Android’s low-level drawing library skia. This has three significant consequences:
The last point makes it awkward to use
Bitmap.copyPixelsToBuffer()at all if you want to inspect individual pixels, because you simply can’t know how skia has been configured to pack channels. As an experiment, try this code:When I run that, I get this output:
We can see that we are dealing with big endian, that the in-memory representation is pre-multiplied and that channels have been re-arranged from ARGB to RGBA (motivated in the skia source code by that that is the same in-memory representation as OpenGL).
If you want to read the pixel data, I suggest you use Bitmap.getPixels() instead. There is some copying involved, but at least the API specifies how the returned data is formated.