ALPHA_8 bitmaps and getPixel

I am trying to load a motion map from a PNG image. To save memory after loading a bitmap, I do something similar.

`Bitmap mapBmp = tempBmp.copy(Bitmap.Config.ALPHA_8, false);` 

If I draw mapBmp, I see the map, but when I use getPixel (), I always get 0 (zero).

Is there a way to get ALPHA information from a bitmap other than with getPixel ()?

+7
source share
4 answers

I managed to find a good and clean way to create border maps. I am creating an ALPHA_8 bitmap from the very beginning. I draw my border map using paths . Then I use copyPixelsToBuffer () and pass the bytes to ByteBuffer . I use the buffer for "getPixels". I think this is a good solution, since you can scale or enlarge the path () and draw the border of the map with the required screen resolution scale and without IO + decoding operations. Bitmap.getPixel () is useless for ALPHA_8 bitmaps, it always returns 0.

0
source

This seems to be an Android error while processing ALPHA_8 . I also tried copyPixelsToBuffer , to no avail. The simplest workaround is to spend a lot of memory and use ARGB_8888 .

Problem 25690

+4
source

I found this question from Google and I was able to extract the pixels using the copyPixelsToBuffer () method that Mitrescu Catalin used. Here's what my code looks like in case anyone else finds this:

 public byte[] getPixels(Bitmap b) { int bytes = b.getRowBytes() * b.getHeight(); ByteBuffer buffer = ByteBuffer.allocate(bytes); b.copyPixelsToBuffer(buffer); return buffer.array(); } 

If you code API level 12 or higher, you can get the total number of bytes instead of getByteCount () . However, if you are encoding API 19 (KitKat), you should probably use getAllocationByteCount () .

+1
source

I developed a solution with the PNGJ library to read an image from assets and then create a Bitmap using Config.ALPHA_8.

 import ar.com.hjg.pngj.IImageLine; import ar.com.hjg.pngj.ImageLineHelper; import ar.com.hjg.pngj.PngReader; public Bitmap getAlpha8BitmapFromAssets(String file) { Bitmap result = null; try { PngReader pngr = new PngReader(getAssets().open(file)); int channels = pngr.imgInfo.channels; if (channels < 3 || pngr.imgInfo.bitDepth != 8) throw new RuntimeException("This method is for RGB8/RGBA8 images"); int bytes = pngr.imgInfo.cols * pngr.imgInfo.rows; ByteBuffer buffer = ByteBuffer.allocate(bytes); for (int row = 0; row < pngr.imgInfo.rows; row++) { IImageLine l1 = pngr.readRow(); for (int j = 0; j < pngr.imgInfo.cols; j++) { int original_color = ImageLineHelper.getPixelARGB8(l1, j); byte x = (byte) Color.alpha(original_color); buffer.put(row * pngr.imgInfo.cols + j, x ^= 0xff); } } pngr.end(); result = Bitmap.createBitmap(pngr.imgInfo.cols,pngr.imgInfo.rows, Bitmap.Config.ALPHA_8); result.copyPixelsFromBuffer(buffer); } catch (IOException e) { Log.e(LOG_TAG, e.getMessage()); } return result; } 

I also invert alpha values ​​due to my special needs. This code is tested only for API 21.

0
source

All Articles