为什么copyPixelsFromBuffer的颜色不正确? setPixels是正确的但很慢 [英] Why is copyPixelsFromBuffer giving incorrect color? setPixels is correct but slow
问题描述
对于我的android应用,我从本机代码中获取了ByteBuffer
.它包含用于创建位图的像素颜色值.
For my android app I am getting a ByteBuffer
from native code. It contains the pixel color values to create a bitmap.
原始图片-
我在位图上使用了copyPixelsFromBuffer
,但是在显示位图时我得到了错误的颜色.
I used copyPixelsFromBuffer
on bitmap, but I am getting incorrect color on displaying the bitmap.
这是此方法的代码-
方法1
ByteBuffer buffer = ...
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
buffer.rewind();
bitmap.copyPixelsFromBuffer(buffer);
大约时间-约0.4毫秒
结果-颜色错误-
Approx. time - ~0.4 ms
Result - Wrong colors -
方法2
接下来,我尝试了setPixels
.它仍然给出错误的颜色,并且速度慢10倍以上,并为int[]
使用了额外的内存.请注意,buffer.hasArray()
是false
,所以我无法从缓冲区获取数组.
Next I tried setPixels
. It still gives wrong colors and is more than 10 times slower and uses extra memory for int[]
. Please note that buffer.hasArray()
is false
, so I can't get array from buffer.
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毫秒
结果-颜色错误-
Approx. time - ~4.0 ms
Result - Wrong colors -
方法3
这次我使用了setPixels
,但是像素值取自ByteBuffer
的IntBuffer
表示形式.颜色是正确的,但是时间仍然很长,并且还有额外的内存分配.
This time I used setPixels
but with the pixel values taken from IntBuffer
representation of ByteBuffer
. The colors are correct but the time is still high and there is extra memory allocation.
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毫秒
结果-正确的颜色-
Approx. time - ~3.0 ms
Result - Correct colors -
有人暗示为什么我用copyPixelsFromBuffer
弄错了颜色吗?我想用它代替setPixels
,因为它更快并且不需要额外的内存分配.
Any hints on why I am getting wrong colors with copyPixelsFromBuffer
? I want to use it instead of setPixels
as it is faster and does not require extra memory allocation.
推荐答案
我发现了问题-尽管据说Bitmap.Config
是ARGB_8888
,但实际上是RGBA
.我认为这是android开发人员文档和代码中的一个巨大错误.
I figured out the problem - even though the Bitmap.Config
is said to be ARGB_8888
, it really is RGBA
. I think it is a huge bug in android developer documentation and code.
此问题中也提到了相同的问题-是Android的ARGB_8888位图内部格式始终是RGBA吗?
The same issue has been noted in this question - Is Android's ARGB_8888 Bitmap internal format always RGBA?
并且ndk文档正确指出格式为ANDROID_BITMAP_FORMAT_RGBA_8888
And the ndk documentation correctly notes the format to be ANDROID_BITMAP_FORMAT_RGBA_8888
解决方案很简单-创建具有RGBA格式的缓冲区.或在Java端切换频道,如下所示-
Solution is simple - create the buffer with RGBA format. Or on the java side switch the channels, something like below -
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);
}
这不是非常有效的代码,但是可以完成工作.
This is not very efficient code, but gets the job done.
这篇关于为什么copyPixelsFromBuffer的颜色不正确? setPixels是正确的但很慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!