Original:http://paulbourke.net/dataformats/bmp/
Введение
Файлы BMP являются уходящими в историю (но все еще широко используемым) форматом файлов для старой (но все еще широко используемой) операционной системы под названием «Windows». Изображения BMP могут варьироваться от черно-белого (1 бит на пиксель) до 24-битного цвета (16,7 миллионов цветов). Хотя изображения могут быть сжаты, это редко используется на практике и не будет обсуждаться здесь подробно.
Структура
Файл BMP состоит из 3 или 4 частей, как показано на диаграмме справа. Первая часть представляет собой заголовок, за ней следует информационный раздел, если изображение индексируется цветом, то следует палитра, и в последнюю очередь это данные пикселя. Положение данных изображения относительно sart файла содержится в заголовке. Информация, такая как ширина и высота изображения, тип сжатия, количество цветов содержится в информационном заголовке.
Заголовок
Заголовок состоит из следующих полей. Обратите внимание, что мы предполагаем, что короткий int состоит из 2 байтов, int из 4 байтов и long int из 8 байтов. Далее мы предполагаем порядок байтов, как для типичных (Intel) машин. Длина заголовка составляет 14 байт.
typedef struct {
unsigned short int type; /* Magic identifier */
unsigned int size; /* File size in bytes */
unsigned short int reserved1, reserved2;
unsigned int offset; /* Offset to image data, bytes */
} HEADER;
Полезными полями в этой структуре являются поле типа (должно быть ‘BM’), которое является простой проверкой того, что это, вероятно, будет законным BMP-файлом, и поле смещения, которое дает число байтов перед фактическими данными пикселя (это относительно начала файла). Обратите внимание, что эта структура не является кратной 4 байтам для тех машин / компиляторов, которые могли бы это предположить, эти машины обычно будут размещать эту структуру на от 2 байт до 16, что приведет к выравниванию будущих вызовов fread ().
Информация
Данные информации об изображении, которые следуют далее, составляют 40 байт в длину, это описано в структуре, приведенной ниже. Поля, представляющие наибольший интерес, представлены шириной и высотой изображения, количеством бит на пиксель (должно быть 1, 4, 8 или 24), числом плоскостей (здесь предполагается 1) и типом сжатия (предполагается, что 0 здесь).
typedef struct {
unsigned int size; /* Header size in bytes */
int width,height; /* Width and height of image */
unsigned short int planes; /* Number of colour planes */
unsigned short int bits; /* Bits per pixel */
unsigned int compression; /* Compression type */
unsigned int imagesize; /* Image size in bytes */
int xresolution,yresolution; /* Pixels per meter */
unsigned int ncolours; /* Number of colours */
unsigned int importantcolours; /* Important colours */
} INFOHEADER;
Типы сжатия, поддерживаемые BMP, перечислены ниже:
- 0 – без сжатия
- Кодирование длиной 1 – 8 бит
- 2 – 4-битовая длина кодирования
- 3 – растровое изображение RGB с маской
Введите только 0 (здесь не будет обсуждаться компрессия).
24-битные данные изображения
Простейшие данные для чтения – 24-битные истинные цветные изображения. В этом случае данные изображения следуют сразу за информационным заголовком, то есть нет цветовой палитры. Оно состоит из трех байтов на пиксель в порядке b, g, r. Каждый байт дает насыщенность для этого компонента цвета, 0 для черного и 1 для белого (полностью насыщенный).
Индексированные данные цвета
Если изображение индексируется цветом, то сразу после заголовка информации будет таблица цветов infoheader.ncolours, каждый из четырех байтов. Первые три байта соответствуют компонентам b, g, r, последний байт зарезервирован / не используется, но, очевидно, может представлять альфа-канал. Для 8-битных изображений в оттенках серого этот цветовой индекс обычно представляет собой градиент серого. Если вы суммируете …. то длина заголовка плюс длина информационного блока плюс 4 кратное количество цветов палитры должны равняться смещению данных изображения. Другими словами
14 + 40 + 4 * infoheader.ncolours = header.offset
Исходный код
Вот источник, предоставленный Michael Sweet, BITMAP.H, BITMAP.C и BMPVIEW.C.
И некоторый пример кода сам, parse.c. Обратите внимание, что ни один из этих сегментов кода не будет обрабатывать все типы файлов BMP, в частности, они не обрабатывают сжатые BMP-файлы. Они должны стать хорошей отправной точкой для встреченных вариантов и для тех, кто хочет писать файлы, совместимые с BMP. С другой стороны, если у вас есть или написан лучший обработчик BMP, то вы можете подать здесь заявку для его добавления.
Вклад Адама Маевски, который пишет один бит на пиксель BMP-файла: pf1bit_bmp.c.
Вклад Гарольда Ходжинса в исправление байтовой упаковки, требуемой для некоторых компиляторов: bitmap2.h.