Вопрос

Я делаю некоторую работу, где я программно загружаю значки с сайтов, указанных в документе OpenSearch, и мне нужно извлечь первое изображение (на данный момент), если оно находится в формате ICO. Я могу прочитать заголовок файла ICO без проблем и вырезать первый файл изображения. Однако после прочтения Запись в Википедии объясняет формат файла Я обнаружил, что, если изображение находится в растровом формате, то файл неполный (ему не хватает заголовка). Поэтому мне нужно реконструировать этот заголовок, прежде чем я смогу сохранить данные в файле, но у меня есть немного сложности.

Согласно Вход в Википедию для формата файла BMP, заголовок длиной 14 байт и должен содержать следующее:

Сметные данные
0x0000    "BM", for our intents and purposes
0x0002    Size of the bitmap file in bytes
0x0006    Dependant on the application creating the file
0x0008    Dependant on the application creating the file
0x000A    Offset of the image data/pixel array

Я подумал, что размер файла растрового изображения в байтах будет размер извлеченного изображения + 14 байтов для заголовка, но я не уверен, что написать на 0X0006, 0x0008 и как доставить местоположение массива пикселей до Напишите на 0x000a.

Я читал статью несколько раз, но я должен признать, что моя голова немного больно. Это мой первый опыт работы с такими вещами. Кто -нибудь может помочь мне понять, как получить местоположение массива пикселей?

Это было полезно?

Решение

0x0006 а также 0x0008 зарезервированы, вы должны просто положить туда нули. Относительно 0x000A, это позиция, в которой фактические данные изображения запускаются в файле. Обычно за заголовком, который у вас есть здесь, следует заголовок DIB (начиная с Offset 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 должны хранить информацию о прозрачности. Вот почему этот измерение имеет размер 16x32 в соответствии с его заголовком DIB, а не с ожидаемым 16x16.

Из Википедия:

Изображения с более чем 32 битами глубины цвета следуют конкретному формату: изображение кодируется как одно изображение, состоящее из цветной маски («маска Xor») вместе с маской непрозрачности («и маска»). Маска XOR должна предшествовать и маски внутри растрового изображения; Если изображение хранится в порядке восходящего вверх (что оно, скорее всего,), маска XOR будет нарисована ниже и маской.

В нашем конкретном случае это означает, что из 256 байт данных изображения первые 64 байта - это маска XOR, последние 64 байта и маска, а только средняя часть - это наше изображение. В нашем конкретном случае вы можете изменить начало данных изображения (смещение 0x000A) до 0x76, чтобы пропустить маску XOR. Тогда вы также измените высоту изображения в заголовке DIB (смещение 0x0016) до 0x10, чтобы убедиться, что маска игнорируется. Здесь эти манипуляции дадут вам достоверную растровую карту, в значительной степени похоже на то, что вы ожидали. В общем случае может быть лучше рассмотреть маски, а не игнорировать их.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top