【发布时间】:2017-11-14 00:08:30
【问题描述】:
在收到来自外部源的字节后,我正在尝试使用 Bitmap.Config.ARGB_8888 在 Android 中创建一个 Bitmap。据我了解,在Bitmap(不使用JNI)中设置原始字节的最快方法是使用copyPixelsFromBuffer() 方法,但是问题在于该缓冲区中字节的正确顺序。
经过反复试验,尽管Config.ARGB_8888 建议ARGB 的正确顺序,但Bitmap 使用的内部格式似乎是RGBA。您可以在Activity 即onCreate() 中使用以下方法测试此行为(我已经在Android 4.4.4 中对其进行了测试,该方法确实测试了copyPixelsToBuffer(),但根据我的测试copyPixelsFromBuffer() 的行为同样):
private void testBitmap() {
// one pixel bitmap
Bitmap bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
// as per javadoc, the int value is in ARGB format, so A=0xFF, R=0x11, G=0x22, B=0x33
bitmap.setPixel(0, 0, 0xFF112233);
ByteBuffer buffer = ByteBuffer.allocateDirect(4); // 4 bytes for the single pixel
bitmap.copyPixelsToBuffer(buffer);
buffer.position(0);
// prints "Bytes: 0x11 0x22 0x33 0xFF" (RGBA)
System.out.println(String.format(Locale.ENGLISH, "Bytes: %s %s %s %s",
toHexString(buffer.get()),
toHexString(buffer.get()),
toHexString(buffer.get()),
toHexString(buffer.get())
));
}
private static String toHexString(byte b) {
return Integer.toHexString(b & 0xFF).toUpperCase();
}
我的问题是:这种内部格式是否记录在任何地方?如果不是,那么我们怎么知道上面的代码在未来的 Android 版本中是否不会中断?或者也许还有其他建议的方法来复制 Bitmap 中的原始字节?
【问题讨论】:
-
不是和
ByteBuffer#order()有关吗?只是猜测...... -
@pskink 不,不是。无论缓冲区的字节顺序如何,结果都是相同的。如果是字节顺序问题,我会期待不同的输出,即
BGRA。我提到的格式仅在 alpha 通道上有所不同 -
哦,确实,我想念你得到
RGBA,而不是你说的BGRA,你不能用int[] arr = new int[1]; bitmap.getPixels(arr, 0, 1, 0, 0, 1, 1); Log.d(TAG, "test: " + Integer.toHexString(arr[0]));代替吗? -
@pskink 我可能会这样做,但是我对字节的情况感兴趣,因为 javadocs 提到涉及缓冲区的复制操作“按原样”复制数据,而
getPixels()/@ 987654343@ 将字节转换为打包的ints。我正在寻找一种方法来避免尽可能多的转化。 -
我明白了,这似乎就是他们命名那些
ARGB_*常量的方式,对于 ndk,它们更精确:developer.android.com/ndk/reference/…