我正在尝试从PNG图像中加载运动地图。为了在加载位图后节省内存,我会执行以下操作。
`Bitmap mapBmp = tempBmp.copy(Bitmap.Config.ALPHA_8, false);`
如果我绘制地图Bmp,我可以看到地图,但当我使用getPixel()时,我总是得到0(零)。
除了使用getPixel()外,还有其他方法从位图中检索ALPHA信息吗?
ALPHA_8
时存在 Android 的 bug。我也尝试了 copyPixelsToBuffer
,但没有效果。最简单的解决方法是浪费大量内存并使用 ARGB_8888
。
public byte[] getPixels(Bitmap b) {
int bytes = b.getRowBytes() * b.getHeight();
ByteBuffer buffer = ByteBuffer.allocate(bytes);
b.copyPixelsToBuffer(buffer);
return buffer.array();
}
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上测试过。
我找到了一种不错而且比较清晰的方法来创建边界地图。我从一开始就创建一个 ALPHA_8 位图。我用路径绘制我的边界地图。然后我使用 copyPixelsToBuffer() 将字节传输到 ByteBuffer 中。我使用缓冲区来从中获取像素。 我认为这是一个很好的解决方案,因为您可以按所需的屏幕分辨率比例缩小或放大路径并绘制边界地图,无需进行 I/O 和解码操作。 Bitmap.getPixel() 对于 ALPHA_8 位图是无用的,它总是返回0。