0x0006
и 0x0008
зарезервированы, вы должны просто поставить нули там. Что касается 0x000A
, это позиция, в которой фактические данные изображения начинаются в файле. Обычно за имеющимся здесь заголовком следует заголовок DIB (начиная со смещения 0x000E
), и первые четыре байта заголовка DIB имеют его размер. Таким образом, вы берете размер заголовка DIB, добавляете его начальное смещение (0x000E
) и получаете позицию, с которой начинаются фактические данные - поместите ее в положение 0x000A
.
Вот пример данных из файла случайного растрового изображения:
42 4D "BM"
2E 78 08 00 Size of the entire bitmap file (0x8782E meaning 555054 bytes)
00 00 creator1, reserved
00 00 creator2, reserved
36 00 00 00 Image data starts at offset 0x36 because the next 0x28 bytes are DIB header
28 00 00 00 DIB header started and its size is 0x28 (40 bytes)
another 36 bytes
FF FF FF First pixel of the image (white as it happens)
Если вы возьмете в качестве примера favicon на serverfault.com , вы возьмете часть файла между смещением 0x0016
и 0x013E
и добавите к ней 42 4D 36 01 00 00 00 00 00 00 36 00 00 00
. Что дает вам своего рода правильный файл растрового изображения - и IrfanView даже отобразит его. Однако данные, хранящиеся в файлах ICO и BMP, не совсем одинаковы, поскольку в файлах ICO необходимо хранить информацию о прозрачности. Вот почему этот favicon имеет размер 16x32 в соответствии с заголовком DIB, а не ожидаемый 16x16.
Из Википедия :
Изображения с глубиной цвета менее 32 бит следуют определенному формату: изображение кодируется как одно изображение, состоящее из цветовой маски («маска XOR») вместе с маской непрозрачности («маска И»). Маска XOR должна предшествовать маске AND внутри данных растрового изображения; если изображение хранится в порядке снизу вверх (что наиболее вероятно), маска XOR будет отображаться под маской AND.
В нашем конкретном случае это означает, что из 256 байтов данных изображения первые 64 байта являются маской XOR, последние 64 байта являются маской AND и только наша средняя часть является нашим изображением. В нашем конкретном случае вы можете изменить начало данных изображения (смещение 0x000A
) на 0x76, чтобы пропустить маску XOR. Затем вы также измените высоту изображения в заголовке DIB (смещение 0x0016
) на 0x10, чтобы маска И игнорировалась. Здесь эти манипуляции дадут вам правильное растровое изображение, очень похожее на то, что вы ожидали. В общем случае, возможно, лучше рассмотреть маски, а не игнорировать их.