对于我的Android应用程序,我从本机代码获得ByteBuffer
。它包含用于创建位图的像素颜色值。
原始图片 -
我在位图上使用copyPixelsFromBuffer
,但在显示位图时颜色不正确。
以下是此方法的代码 -
方法1
ByteBuffer buffer = ...
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
buffer.rewind();
bitmap.copyPixelsFromBuffer(buffer);
方法2
接下来我尝试了setPixels
。它仍然提供错误的颜色,速度慢10倍以上,并为int[]
使用额外的内存。请注意buffer.hasArray()
为false
,因此我无法从缓冲区获取数组。
ByteBuffer buffer = ...
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
buffer.rewind();
int[] pixels = new int[width * height];
for (int i = 0; i < width * height; i++) {
int a = buffer.get();
int r = buffer.get();
int g = buffer.get();
int b = buffer.get();
pixels[i] = a << 24 | r << 16 | g << 8 | b;
}
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
约时间 - ~4.0 ms
结果 - 颜色错误 -
方法3
这次我使用了setPixels
,但像素值取自IntBuffer
ByteBuffer
的{{1}}表示。颜色是正确的,但时间仍然很长,并有额外的内存分配。
ByteBuffer buffer = ...
IntBuffer intBuffer = buffer.asIntBuffer();
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
buffer.rewind();
int[] pixels = new int[width * height];
for (int i = 0; i < width * height; i++) {
pixels[i] = intBuffer.get();
}
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
约时间 - ~3.0毫秒
结果 - 正确的颜色 -
有关为什么我使用copyPixelsFromBuffer
获取错误颜色的任何提示?我想使用它代替setPixels
,因为它更快,不需要额外的内存分配。
答案 0 :(得分:1)
我发现了问题 - 即使Bitmap.Config
被称为ARGB_8888
,它确实是RGBA
。我认为这是android开发人员文档和代码中的一个巨大错误。
在这个问题中已经注意到同样的问题 - https://docs.mongodb.com/manual/core/index-text/
ndk文档正确地指出格式为ANDROID_BITMAP_FORMAT_RGBA_8888
解决方案很简单 - 使用RGBA格式创建缓冲区。或者在java端切换频道,如下所示 -
for (int i = 0; i < width * height; i++) {
Byte a = buffer.get();
Byte r = buffer.get();
Byte g = buffer.get();
Byte b = buffer.get();
bufferCopy.put(r);
bufferCopy.put(g);
bufferCopy.put(b);
bufferCopy.put(a);
}
这不是非常有效的代码,但可以完成工作。