Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых

Графический интерфейс GDI в Microsoft Windows

© Александр Фролов, Григорий Фролов
Том 4, М.: Диалог-МИФИ, 1993, 288 стр.

[Назад] [Содеожание] [Дальше]

4.3. Битовые изображения в формате DIB

Как мы уже говорили, битовые изображения DDB имеют один существенный недостаток - они "привязаны" к конкретному типу устройства вывода. В графической оболочке Presentation Manager операционной системы OS/2 впервые был использован аппаратно-независимый формат для хранения изображений, который называется DIB.

В операционной системе Windows версии 3.0 этот формат получил свое дальнейшее развитие. В частности, была добавлена возможность хранения изображения в компрессованном виде. К сожалению, использованный алгоритм компрессии дает хорошие результаты только для таких изображений, которые содержат большие одинаково закрашенные области. Операционная система Windows NT позволяет использовать новые форматы изображений DIB и произвольные методы компрессии, такие как, например, JPEG (очень эффективный метод компрессии графических изображений, при котором можно ценой потери качества получить практически любую степень сжатия).

В программном интерфейсе Windows нет функции, специально предназначенной для рисования битовых изображений DIB. Поэтому если вы создаете приложение, которое должно отображать bmp-файлы на экране или печатать их на принтере, вам придется иметь дело с внутренней структурой этих файлов. Мы познакомим вас с форматом всех необходимых структур данных, имеющих отношение к bmp-файлам.

Форматы файлов и структур данных

Если рассматривать структуру bmp-файлов в общем, для нас интересны два формата. Первый формат используется в Windows версий 3.х, второй - в графической оболочке Presentation Manager операционной системы OS/2 версий 1.х. Первый из этих форматов является естественным для приложений Windows. Что же касается второго формата, такие приложения, как Paint Brush, способны конвертировать его в стандартный формат Windows.

Ваше приложение может либо полностью проигнорировать формат bmp-файлов оболочки Presentation Manager, либо (что лучше) автоматически преобразовывать его к формату Windows, как это делают стандартные приложения Windows.

Формат bmp-файлов Windows

Формат bmp-файлов для операционной системы Windows версий 3.0 и 3.1 представлен на рис. 4.4 (в более старых версиях bmp-файлы содержали битовые изображения в формате DDB).

Рис. 4.4. Формат bmp-файла для Windows версии 3.х

Файл, содержащий битовое изображение, начинается со структуры BITMAPFILEHEADER. Эта структура описывает тип файла и его размер, а также смещение области битов изображения.

Сразу после структуры BITMAPFILEHEADER в файле следует структура BITMAPINFO, которая содержит описание изображения и таблицу цветов. Описание изображения (размеры изображения, метод компрессии, размер таблицы цветов и т. д.) находится в структуре BITMAPINFOHEADER. В некоторых случаях (не всегда) в файле может присутствовать таблица цветов (как массив структур RGBQUAD), присутствующих в изображении.

Биты изображения обычно располагаются сразу после таблицы цветов. Точное значение смещения битов изображения находится в структуре BITMAPFILEHEADER.

Структура BITMAPFILEHEADER , а также указатели на нее, описаны в файле windows.h:

typedef struct tagBITMAPFILEHEADER
{
  UINT   bfType;
  DWORD  bfSize;
  UINT   bfReserved1;
  UINT   bfReserved2;
  DWORD  bfOffBits;
} BITMAPFILEHEADER;
typedef BITMAPFILEHEADER*      PBITMAPFILEHEADER;
typedef BITMAPFILEHEADER FAR* LPBITMAPFILEHEADER;

Структура BITMAPFILEHEADER одинакова как для bmp-файлов Windows, так и для bmp-файлов оболочки Presentation Manager (рис. 4.5). И в том, и в другом случае она расположена в начале файла и обычно используется для идентификации типа файла.

Приведем описание полей этой структуры.

Поле Описание
bfType Тип файла. Поле содержит значение 0x4D42 (текстовая строка "BM"). Анализируя содержимое этого поля, приложение может идентифицировать файл как содержащий битовое изображение
bfSize Размер файла в байтах. Это поле может содержать неправильное значение, так как в SDK для Windows версии 3.0 поле bfSize было описано неправильно (утверждалось, что это поле содержит размер файла в двойных словах). Обычно содержимое этого поля игнорируется, так как из-за ошибки в документации старые приложения устанавливали в этом поле неправильное значение
bfReserved1 Зарезервировано, должно быть равно 0
bfReserved2 Зарезервировано, должно быть равно 0
bfOffBits Смещение битов изображения от начала файла в байтах. Область изображения не обязательно должна быть расположена сразу вслед за заголовками файла или таблицей цветов (если она есть)

В структуре BITMAPFILEHEADER для нас важны два поля - поле bfType, определяющее тип файла, и поле bfOffBits, определяющее смещение битов, из которых формируется изображение. Остальные поля можно проигнорировать. В частности, размер файла нетрудно определить средствами файловой системы MS-DOS.

Сразу после структуры BITMAPFILEHEADER в bmp-файле расположена структура BITMAPINFO (для изображений Windows) или BITMAPCOREINFO (для изображений Presentation Manager).

Структура BITMAPINFO и указатели на нее описаны в файле windows.h следующим образом:

typedef struct tagBITMAPINFO
{
  BITMAPINFOHEADER bmiHeader;
  RGBQUAD          bmiColors[1];
} BITMAPINFO;
typedef BITMAPINFO*     PBITMAPINFO;
typedef BITMAPINFO FAR* LPBITMAPINFO;

Структура BITMAPINFOHEADER описывает размеры и способ представления цвета в битовом изображении:

typedef struct tagBITMAPINFOHEADER
{
   DWORD  biSize;
   LONG   biWidth;
   LONG   biHeight;
   WORD   biPlanes;
   WORD   biBitCount;
   DWORD  biCompression;
   DWORD  biSizeImage;
   LONG   biXPelsPerMeter;
   LONG   biYPelsPerMeter;
   DWORD  biClrUsed;
   DWORD  biClrImportant;
} BITMAPINFOHEADER;
typedef BITMAPINFOHEADER*      PBITMAPINFOHEADER;
typedef BITMAPINFOHEADER FAR* LPBITMAPINFOHEADER;

Опишем назначение отдельных полей этой структуры.

Поле Описание
biSize Размер структуры BITMAPINFOHEADER в байтах
biWidth Ширина битового изображения в пикселах
biHeight Высота битового изображения в пикселах
biPlanes Количество плоскостей в битовом изображении. Содержимое этого поля должно быть равно 1
biBitCount Количество битов на один пиксел. Может быть равно 1, 4, 8 или 24. Для новых 16- и 32-битовых форматов файлов DIB, используемых в Windows NT, в этом поле могут находиться также значения 16 и 32
biCompression Метод компрессии. Может принимать одно из следующих значений:BI_RGB - компрессия не используетсяBI_RLE4 - компрессия изображений, в которых для представления пиксела используется 4 бита. При использовании этого метода компрессии содержимое поля biBitCount должно быть равно 4BI_RLE8 - компрессия изображений, в которых для представления пиксела используется 8 бит. При использовании этого метода компрессии содержимое поля biBitCount должно быть равно 8BI_BITFIELDS - другой формат компрессии. Это значение используется для Windows NT. Соответствующая константа описана в файле windows.h, который поставляется вместе со средствами разработки приложений Windows NT
biSizeImage Размер изображения в байтах. Это поле содержит размер, необходимый для хранения разжатого изображения. Если компрессия не используется (в поле biCompression находится значение BI_RGB), содержимое поля biSizeImage может быть равно 0
biXPelsPerMeter Разрешение устройства вывода по горизонтали в пикселах на метр, необходимое для вывода битового изображения без искажений. Это поле используется не всегда. Если оно не используется, в нем следует установить нулевое значение.
biYPelsPerMeter Разрешение устройства вывода по вертикали в пикселах на метр, необходимое для вывода битового изображения без искажений. Это поле, как и предыдущее, используется не всегда. Если оно не используется, в нем следует установить нулевое значение
biClrUsed Размер таблицы цветов. Это поле определяет размер массива структур RGBQUAD (рис. 4.4), расположенного в файле сразу после структуры BITMAPINFOHEADER. Если в этом поле находится нулевое значение, размер таблицы цветов зависит от количества бит, используемых для представления цвета одного пиксела (поле biBitCount)
biClrImportant Количество цветов, необходимое для отображения файла без искажений. Обычно в этом поле находится нулевое значение, в этом случае важны все цвета

Сразу после структуры BITMAPINFOHEADER в фале может находиться таблица цветов. Эта таблица содержит массив структур RGBQUAD :

typedef struct tagRGBQUAD
{
  BYTE  rgbBlue;
  BYTE  rgbGreen;
  BYTE  rgbRed;
  BYTE  rgbReserved;
} RGBQUAD;
typedef RGBQUAD FAR* LPRGBQUAD;

Поля rgbBlue, rgbGreen и rgbRed содержат RGB-компоненты цветов, поле rgbReserved зарезервировано и должно содержать нулевое значение.

Как мы уже говорили, файл битового изображения может содержать таблицу цветов, а может и не содержать ее. Приведем зависимость размера таблицы цветов в зависимости от значения поля biBitCount (количество бит, используемых для представления одного пиксела):

Значение biBitCount Размер таблицы цветов
1 2
4 16
8 256
24 не используется

Если содержимое поля biClrUsed отлично от нуля, используется таблица цветов уменьшенного размера. В ней описаны только те цвета, которые содержатся в изображении.

Формат bmp-файлов Presentation Manager

Оболочка Presentation Manager операционной системы OS/2 использует другой формат bmp-файла (рис. 4.5).

Рис. 4.5. Формат bmp-файла для Presentaton Manager операционной системы OS/2 версии 1.х

В самом начале файла расположена структура BITMAPFILEHEADER. Ее формат полностью соответствует формату аналогичной структуры bmp-файлов операционной системы Windows. В этой структуре, в частности, есть информация о смещении области битов изображения относительно начала файла.

После структуры BITMAPFILEHEADER в файле располагается структура BITMAPCOREINFO, содержащая структуру BITMAPCOREHEADER и таблицу цветов в виде массива структур RGBTRIPLE :

typedef struct tagBITMAPCOREINFO
{
   BITMAPCOREHEADER bmciHeader;
   RGBTRIPLE        bmciColors[1];
} BITMAPCOREINFO;
typedef BITMAPCOREINFO*      PBITMAPCOREINFO;
typedef BITMAPCOREINFO FAR* LPBITMAPCOREINFO;

Формат структуры BITMAPCOREHEADER приведен ниже:

typedef struct tagBITMAPCOREHEADER
{
   DWORD bcSize;
   short bcWidth;
   short bcHeight;
   WORD  bcPlanes;
   WORD  bcBitCount;
} BITMAPCOREHEADER;
typedef BITMAPCOREHEADER*      PBITMAPCOREHEADER;
typedef BITMAPCOREHEADER FAR* LPBITMAPCOREHEADER;

Приведем описание отдельных полей этой структуры.

Поле Описание
bcSize Размер структуры BITMAPCOREHEADER в байтах
bcWidth Ширина битового изображения в пикселах
bcHeight Высота битового изображения в пикселах
bcPlanes Количество плоскостей в битовом изображении. Содержимое этого поля должно быть равно 1
bcBitCount Количество битов на один пиксел. Может быть равно 1, 4, 8 или 24

Таблица цветов в bmp-файле в формате Presentation Manager расположена после структуры BITMAPCOREHEADER и представляет собой массив структур RGBTRIPLE , содержащих RGB-компоненты цвета:

typedef struct tagRGBTRIPLE
{
   BYTE  rgbtBlue;
   BYTE  rgbtGreen;
   BYTE  rgbtRed;
} RGBTRIPLE;
typedef RGBTRIPLE FAR* LPRGBTRIPLE;

Зная количество битов, используемых для представления одного пиксела изображения, нетрудно определить количество элементов в таблице цветов:

wClrUsed = 1 << bcBitCount;

Биты изображения

Формат области битов изображения одинаковый для некомпрессованых bmp-файлов Windows и bmp-файлов Presentation Manager (оболочка Presentation Manager операционной системы OS/2 версии 1.х не работает с компрессованными файлами).

Каждая строка битового изображения (scan line) хранится в буфере, длина которого кратна двойному слову DWORD. Для черно/белых изображений каждый бит буфера используется для представления цвета одного пиксела (если не используется компрессия).

Формат области битов изображения для bmp-файлов не зависит от аппаратных особенностей какого-либо устройства отображения. Всегда используется одна цветовая плоскость, при этом цвет пиксела представляется разным количеством бит памяти, в зависимости от цветового разрешения изображения.

Последнее обстоятельство может оказаться полезным, например, при печати изображения на принтере, способным работать с оттенками серого цвета. В этом случае драйвер принтера сможет использовать избыточную цветовую информацию, содержащуюся в bmp-файле, для формирования полутонового изображения.

В памяти изображение хранится в перевернутом виде. Поэтому, например, изображение, показанное на рис. 4.1 после вывода будет иметь вид, показанный на рис. 4.6.

Рис. 4.6. Изображение в окне Windows

В отличие от изображений DDB, при работе с изображениями DIB используется система координат, начало которой расположено в левом нижнем углу, а координатные оси направлены вверх и вправо.

Если ваше приложение загружает изображение в оперативную память, необходимо предварительно определить размер буфера. Если изображение не компрессовано (т. е. в поле biCompression структуры BITMAPINFOHEADER находится значение BI_RGB), для вычисления размера буфера можно воспользоваться следующей формулой:

dwSizeImage = ((nBits + 31)/32 * 4) * biHeight

где

nBits = biBitCount * biWidth

В этих формулах переменные biHeight, biBitCount и biWidth являются полями структуры BITMAPINFOHEADER.

Если же изображение хранится в компрессованом формате (в поле biCompression структуры BITMAPINFOHEADER находятся значения BI_RLE4 или BI_RLE8), нужный размер буфера можно получить из поля biSizeImage структуры BITMAPINFOHEADER.

Формат области битов изображения для цветных файлов сложнее, однако размер области определяется аналогично.

Как правило, приложения не формируют сложные изображения непосредственно в оперативной памяти, а загружают их из bmp-файлов. Однако иногда требуется создать простое черно/белое изображение непосредственно в памяти. В этом случае требуется знать точный формат области битов изображения.

Но в большинстве случаев для вывода готового изображения от вас требуется только умение определить размер области битов изображения для получения соответствующего буфера, куда эта область загружается из bmp-файла перед выводом изображения на экран. Поэтому мы не будем рассматривать формат области битов изображения для цветных bmp-файлов. Отметим только, что для bmp-файлов в формате DIB для представления цвета одного пиксела используются несколько бит памяти. Например, в 16-цветных файлах цвет пиксела представляется при помощи 4 бит памяти, в 256-цветных файлах для этой цели используется 8 бит, файлы True Color используют 24 бита.

[Назад] [Содеожание] [Дальше]