Стэн Трухильо - Графика для Windows средствами DirectDraw Страница 31

Тут можно читать бесплатно Стэн Трухильо - Графика для Windows средствами DirectDraw. Жанр: Компьютеры и Интернет / Программирование, год неизвестен. Так же Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте «WorldBooks (МирКниг)» или прочесть краткое содержание, предисловие (аннотацию), описание и ознакомиться с отзывами (комментариями) о произведении.
Стэн Трухильо - Графика для Windows средствами DirectDraw

Стэн Трухильо - Графика для Windows средствами DirectDraw краткое содержание

Прочтите описание перед тем, как прочитать онлайн книгу «Стэн Трухильо - Графика для Windows средствами DirectDraw» бесплатно полную версию:

Стэн Трухильо - Графика для Windows средствами DirectDraw читать онлайн бесплатно

Стэн Трухильо - Графика для Windows средствами DirectDraw - читать книгу онлайн бесплатно, автор Стэн Трухильо

BMP — стандартный формат графических файлов Windows. Подавляющее большинство BMP-файлов хранится без сжатия, что облегчает работу с ними. Даже в сжатых BMP-файлах нет ничего особенно сложного, но мы ограничимся файлами без сжатия.

BMP-файлы состоят из трех основных частей:

• заголовок;

• палитра;

• графические данные (значения пикселей).

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

Палитра присутствует только в BMP-файлах, содержащих палитровые изображения (с глубиной пикселей 8 бит и менее). К 8-битным изображениям прикладывается палитра, состоящая из не более чем 256 элементов.

Графические данные — это и есть само изображение. Формат этих данных зависит от глубины пикселей. Хотя BMP-файлы делятся на несколько типов, мы ограничимся 8-битными и 24-битными изображениями. 8-битные BMP-файлы будут использоваться для работы с 8-битными поверхностями, а 24-битные — для беспалитровых поверхностей. Хотя, по слухам, в природе существуют 16-битные и 32-битные BMP-файлы, они встречаются очень редко — например, мне таковые ни разу не попадались. Впрочем, это не имеет особого значения, так как 24-битную графику можно легко преобразовать в 16- или 32-битный формат.

Структура заголовка

Данные заголовка BMP-файла хранятся в двух структурах: BITMAPFILEHEADER и BITMAPINFOHEADER. Структура BITMAPFILEHEADER присутствует в начале любого BMP-файла и содержит информацию о самом файле. Для нас в этой структуре представляет интерес лишь одно поле — bfType, сигнатура BMP-файла (информацию об остальных полях можно найти в справочной системе Visual C++). В BMP-файлах это поле содержит буквы BM (обе буквы — прописные). По содержимому этого поля мы будем убеждаться в том, что выбранные файлы действительно имеют формат BMP.

Структура BITMAPINFOHEADER содержит информацию об изображении, хранящемся в BMP-файле. Эта структура объявляется так:

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, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;

Первое поле, biSize, определяет размер структуры BITMAPINFOHEADER в байтах. Если ваша программа создает BMP-файл, это поле заполняется тривиально — достаточно определить размер структуры функцией sizeof. Однако при чтении BMP-файла по содержимому этого поля приходится рассчитывать позицию файла, на которой структура заголовка кончается. Эта мера обеспечивает обратную совместимость, благодаря ей Microsoft в будущем сможет увеличить размер структуры BITMAPINFOHEADER, не нарушая работы существующих приложений.

СОВЕТ

Лучше молчать и прослыть глупцом…

Когда я только начал программировать для Windows, то не понимал, зачем в некоторые структуры включаются поля с их размерами. Забыв о мудром совете Авраама Линкольна, я высказался на эту тему в одной из ранних статей и был справедливо наказан. Впрочем, если бы все прислушались к совету Линкольна, никто бы не писал книг.

Поля biWidth, biHeight и biBitCount определяют размеры изображения. Содержимое поля biCompression позволяет узнать, хранится ли изображение в сжатом виде. Поскольку мы не собираемся работать со сжатыми BMP-файлами, необходимо проверить, имеет ли это поле значение BI_RGB (а не BI_RLE8, свидетельствующее о сжатии файла).

В поле biSizeImage хранится размер графических данных (в пикселях). Однако учтите, что это поле часто оказывается незаполненным (содержит нулевое значение). В таких случаях нам придется самостоятельно вычислять размер графических данных.

Наконец, поле biClrUsed определят количество цветов в палитре (для палитровых изображений). Как и поле biSizeImage, оно часто может быть равно нулю. Это означает, что палитра содержит максимальное количество элементов (256 для 8-битных изображений). Остальные поля структуры BITMAPINFOHEADER не представляют для нас интереса, поэтому я не стану утомлять вас их обсуждением. 

Палитра 

Палитра в BMP-файлах хранится в виде списка структур RGBQUAD, где каждый элемент представляет отдельный цвет. Структура RGBQUAD объявляется так:

typedef struct tagRGBQUAD {

 BYTE rgbBlue;

 BYTE rgbGreen;

 BYTE rgbRed;

 BYTE rgbReserved;

} RGBQUAD;

В первых трех полях хранятся цветовые RGB-составляющие. На поле rgbReserved мы не будем обращать внимания (предполагается, что оно равно нулю). Как я упоминал выше, количество структур RGBQUAD в BMP-файле определяется полем biClrUsed. Тем не менее обычно 8-битные BMP-файлы содержат 256 структур RGBQUAD. В 24-битных RGB-файлах структуры RGBQUAD отсутствуют. 

Графические данные 

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

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

Изображения хранятся в BMP-файлах в перевернутом виде, так что первая строка пикселей файла на самом деле является нижней строкой настоящего изображения. Чтобы восстановить нормальное изображение, мы начнем чтение файла с последней строки пикселей и будем двигаться к началу. 

Организация доступа к поверхностям 

В наших программах чтением BMP-файлов занимается класс DirectDrawWin. Впервые эта возможность была использована в главе 3, где в программе Bounce BMP-файл загружался на поверхность. То же самое происходит и в программе BmpView, но сначала давайте рассмотрим соответствующий программный код.

Поддержка работы с BMP-файлами в классе DirectDrawWin обеспечивается функцией CreateSurface(). Существуют две версии CreateSurface(): первая в качестве аргументов получает параметры поверхности, а вторая — имя BMP-файла. Вторая версия CreateSurface() загружает BMP-файл, затем создает новую поверхность, параметры которой совпадают с параметрами изображения, и копирует содержимое файла на поверхность. 

Функция CreateSurface() 

Функция CreateSurface() требует, чтобы изображение в передаваемом BMP-файле было палитровым или беспалитровым в зависимости от текущего видеорежима. Она не станет загружать палитровые изображения на беспалитровую поверхность, и наоборот. В принципе это возможно, но непрактично. Загрузить палитровое изображение на беспалитровую поверхность довольно просто, но глупо, потому что при этом будет использоваться лишь малая часть возможностей поверхности (всего 256 цветов из 16 миллионов). С другой стороны, загрузка беспалитровых изображений на палитровую поверхность потребует программного сокращения миллионов цветов до 256-цветной палитры.

Давайте посмотрим, как реализована функция CreateSurface() (см. листинг 5.1).

Листинг 5.1. Функция CreateSurface()

LPDIRECTDRAWSURFACE DirectDrawWin::CreateSurface(LPCTSTR filename, BOOL installpalette) {

 int imagew, imageh;

 GetBmpDimensions(filename, imagew, imageh);

 LPDIRECTDRAWSURFACE surf=CreateSurface(imagew, imageh);

 if (surf==0) {

  TRACE("CreateSurface(filename) failed to create surface\n");

  return 0;

 }

 ifstream bmp(filename, ios::binary | ios::nocreate);

 if (!bmp.is_open()) {

  TRACE("LoadSurface: cannot open Bmp file\n");

  return 0;

 }

 BITMAPFILEHEADER bmpfilehdr;

 bmp.read((char*)&bmpfilehdr, sizeof(bmpfilehdr));

 char* ptr=(char*)&bmpfilehdr.bfType;

 if (*ptr!='B' || *++ptr!='M') {

  TRACE("invalid bitmap\n");

  return 0;

 }

 BITMAPINFOHEADER bmpinfohdr;

 bmp.read((char*)&bmpinfohdr, sizeof(bmpinfohdr));

 bmp.seekg(sizeof(bmpfilehdr)+bmpinfohdr.biSize, ios::beg);

 int imagebitdepth=bmpinfohdr.biBitCount;

 int imagesize=bmpinfohdr.biSizeImage;

 if (imagesize==0) imagesize=((imagew*(imagebitdepth/8)+3) & ~3)*imageh;

 if (bmpinfohdr.biCompression!=BI_RGB) {

  TRACE("compressed BMP format\n");

  return 0;

 }

 TRACE("loading '%s': width=%d height=%d depth=%d\n", filename, imagew, imageh, imagebitdepth);

Перейти на страницу:
Вы автор?
Жалоба
Все книги на сайте размещаются его пользователями. Приносим свои глубочайшие извинения, если Ваша книга была опубликована без Вашего на то согласия.
Напишите нам, и мы в срочном порядке примем меры.
Комментарии / Отзывы
    Ничего не найдено.