Я пытаюсь создать изображение из двоичного файла. Файл содержит значок 32x32 и соответствующую ему 16 цветовую палитру.
Спецификация
Значок имеет длину 512 байт. Значок разделен на плитки размером 4х4. Размер каждой плитки 4х8.
Вот расположение байтов 4x8 для одной плитки:
B B B B
B B B B
B B B B
B B B B
B B B B
B B B B
B B B B
B B B B
Вот биты, расширенные из вышеуказанных байтов:
11110000 11110000 11110000 11110000
00001111 00001111 00001111 00001111
11110000 11110000 11110000 11110000
00001111 00001111 00001111 00001111
11110000 11110000 11110000 11110000
00001111 00001111 00001111 00001111
11110000 11110000 11110000 11110000
00001111 00001111 00001111 00001111
Разбиение каждого байта на четыре пикселя каждый дает следующую плитку:
1111 0000 1111 0000 1111 0000 1111 0000
0000 1111 0000 1111 0000 1111 0000 1111
1111 0000 1111 0000 1111 0000 1111 0000
0000 1111 0000 1111 0000 1111 0000 1111
1111 0000 1111 0000 1111 0000 1111 0000
0000 1111 0000 1111 0000 1111 0000 1111
1111 0000 1111 0000 1111 0000 1111 0000
0000 1111 0000 1111 0000 1111 0000 1111
Каждый 4-битный является индексом цвета в палитре.
Цветовая палитра длиной 32 байта содержит 16 цветов. Каждый цвет составляет 16 бит (5 для каждого компонента, в то время как последний не используется).
Проблема - Шаг 1
Мне удалось разобрать данные изображения в массив из 512 байтов, а цветовую палитру - в массив из 32 байтов. Но я не совсем уверен, как продолжить дальше.
Я прочитал все байты данных изображения в BitSet, но я не уверен, что это даже полезно.
Кроме того, я не знаю, как создать цвет из двух байтов.
Любая помощь / предложения / комментарии?
Спасибо.
Проблема - Шаг 2
Итак, с вашей помощью я создал IndexColorModel из цветовой палитры следующим образом:
int[] colors = new int[16*3];
for (int i = 0; i < 16; i++) {
byte b1 = this.palette[i]; // byte 1: 5 bits of R and 3 bits of G
byte b2 = this.palette[i+1]; // byte 2: 2 bits of G and 5 bits of B and 0.
// colors are encoded in inverse order
colors[i+2] = (b2 & 0x3E) >>> // red
colors[i+1] = ((b1 & 0x07) << 2) | ((b2 & 0xC0) >> 6); // green
colors[i] = (b1 & 0xF8) >>> 3; // blue
}
IndexColorModel cm = new IndexColorModel(5, 16*3, colors, 0, false, 0, DataBuffer.TYPE_BYTE);
Теперь мне нужно создать BufferedImage из массива байтов, которые я прочитал из двоичного файла, используя вышеупомянутый IndexColorModel.
Пока у меня есть это:
DataBuffer buffer = new DataBufferByte(this.titleData, 32*32);
int pixelStride = 4; //assuming r, g, b, skip, r, g, b, skip...
int scanlineStride = 4*32; //no extra padding
int[] bandOffsets = {0, 1, 2}; //r, g, b
WritableRaster raster = Raster.createInterleavedRaster(buffer, 32, 32, scanlineStride, pixelStride, bandOffsets, null);
boolean isAlphaPremultiplied = false;
BufferedImage bim = new BufferedImage(cm, raster, isAlphaPremultiplied, null);
Взято из здесь .
this.titleData - это массив из 512 байтов, который считывается из двоичного файла.
Приведенный выше код выдает следующее исключение:
Причина: java.awt.image.RasterFormatException: массив данных слишком мал (должно быть 4094)
Любая помощь? Еще раз большое спасибо.