【发布时间】:2018-06-06 19:29:26
【问题描述】:
对于我的 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。颜色是正确的,但时间仍然很长,还有额外的内存分配。
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 ms
结果 - 正确颜色 -
关于我为什么使用copyPixelsFromBuffer 得到错误颜色的任何提示?我想使用它而不是 setPixels,因为它更快并且不需要额外的内存分配。
【问题讨论】:
-
我怀疑是色彩空间问题,但我不太明白如何才能让您的第三次尝试正常工作。使用
bitmap.copyPixelsToBuffer()根据方法 3 的结果创建一个新缓冲区可能是一个不错的实验,然后检查两个缓冲区之间的差异。这可能有助于诊断问题。 -
只是想到了别的东西:确保缓冲区的字节顺序设置为
ByteOrder.LITTLE_ENDIAN。那里的不匹配可能会导致奇怪的颜色效果。 -
感谢@TedHopp,关于使用
copyPixelsToBuffer()比较缓冲区的提示非常有帮助。我意识到了这个问题 - 缓冲区是 ARGB,但位图需要 RGBA。 -
很高兴你知道了!您应该将您的答案标记为解决方案。
标签: android performance colors bitmap bytebuffer