我正在尝试编写一些方法,将Android位图转换为RGBA字节数组,然后再将其转换回位图。问题在于,我似乎没有找到正确的公式,因为颜色总是出错。我尝试了几种不同的假设,但都无济于事。
所以,这是从位图转换为RGBA的方法,我认为是正确的:
public static byte[] bitmapToRgba(Bitmap bitmap) {
int[] pixels = new int[bitmap.getWidth() * bitmap.getHeight()];
byte[] bytes = new byte[pixels.length * 4];
bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
int i = 0;
for (int pixel : pixels) {
// Get components assuming is ARGB
int A = (pixel >> 24) & 0xff;
int R = (pixel >> 16) & 0xff;
int G = (pixel >> 8) & 0xff;
int B = pixel & 0xff;
bytes[i++] = (byte) R;
bytes[i++] = (byte) G;
bytes[i++] = (byte) B;
bytes[i++] = (byte) A;
}
return bytes;
}
这是一种从这些字节中创建位图的方法,但效果并不如预期:
public static Bitmap bitmapFromRgba(int width, int height, byte[] bytes) {
int[] pixels = new int[bytes.length / 4];
int j = 0;
// It turns out Bitmap.Config.ARGB_8888 is in reality RGBA_8888!
// Source: https://dev59.com/rafja4cB1Zd3GeqP0sS3#47982505
// Now, according to my own experiments, it seems it is ABGR... this sucks.
// So we have to change the order of the components
for (int i = 0; i < pixels.length; i++) {
byte R = bytes[j++];
byte G = bytes[j++];
byte B = bytes[j++];
byte A = bytes[j++];
int pixel = (A << 24) | (B << 16) | (G << 8) | R;
pixels[i] = pixel;
}
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(IntBuffer.wrap(pixels));
return bitmap;
}
这是我最后的实现,尽管我尝试了几种不同的方法都没有成功。我假设createBitmap期望ABGR,尽管指定了ARGB_8888,因为我已经进行了硬编码像素的实验,例如:
0xff_ff_00_00 -> got blue
0xff_00_ff_00 -> got green
0xff_00_00_ff -> got red
无论如何,也许这种假设是错误的,可能是之前某个错误的假设的结果。
我认为主要问题可能与使用有符号数字值有关,因为 Java 中没有无符号数(好吧,在 Java 8+ 中有一些东西,但一方面我认为不必使用这些东西,另一方面它也不受我需要支持的旧 Android 版本支持)。
非常感谢您的任何帮助。
提前感谢您!