ALPHA_8 bitmaps and getPixel

8

我正在尝试从PNG图像中加载运动地图。为了在加载位图后节省内存,我会执行以下操作。

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

如果我绘制地图Bmp,我可以看到地图,但当我使用getPixel()时,我总是得到0(零)。

除了使用getPixel()外,还有其他方法从位图中检索ALPHA信息吗?

4个回答

5
似乎在处理 ALPHA_8 时存在 Android 的 bug。我也尝试了 copyPixelsToBuffer,但没有效果。最简单的解决方法是浪费大量内存并使用 ARGB_8888

问题25690


2
我在谷歌上找到了这个问题,并使用Mitrescu Catalin最终使用的copyPixelsToBuffer()方法提取了像素。如果其他人也遇到了同样的问题,这是我的代码:
public byte[] getPixels(Bitmap b) {
    int bytes = b.getRowBytes() * b.getHeight();
    ByteBuffer buffer = ByteBuffer.allocate(bytes);
    b.copyPixelsToBuffer(buffer);
    return buffer.array();
}

如果您的编码是针对API级别12或更高版本,则可以使用getByteCount()来获取要分配的总字节数。但是,如果您的编码是针对API级别19(KitKat),则最好使用getAllocationByteCount()

即使是copyPixelsToBuffer()在我的情况下也会返回零。 - zelig74

1
我使用PNGJ库开发了一个解决方案,可以从assets中读取图像然后创建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;

}

我还反转了Alpha值,因为我的特殊需求。这段代码仅在API 21上测试过。


1

我找到了一种不错而且比较清晰的方法来创建边界地图。我从一开始就创建一个 ALPHA_8 位图。我用路径绘制我的边界地图。然后我使用 copyPixelsToBuffer() 将字节传输到 ByteBuffer 中。我使用缓冲区来从中获取像素。 我认为这是一个很好的解决方案,因为您可以按所需的屏幕分辨率比例缩小或放大路径并绘制边界地图,无需进行 I/O 和解码操作。 Bitmap.getPixel() 对于 ALPHA_8 位图是无用的,它总是返回0。


请问您能否提供一个示例,说明如何提取“ALPHA_8”位图的“像素”?我一直得到0... - Mihai Todor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接