Я пытаюсь написать пару методов для преобразования растрового изображения 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://stackoverflow.com/a/47982505/1160360
// 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
В любом случае, возможно, это предположение неверно и является следствием какого-то другого ошибочного ранее.
Я думаю, что основная проблема может быть связана с использованием значений числовых c со знаком, поскольку в Java нет беззнаковых значений (ну, в Java 8+ есть что-то, но с одной стороны Я не думаю, что это необходимо, и с другой стороны, оно не поддерживается более старыми Android версиями, которые мне нужно поддерживать).
Любая помощь будет очень признательна.
Заранее большое спасибо!