Графика для Windows средствами DirectDraw
Шрифт:
Лучше молчать и прослыть глупцом…
Когда я только начал программировать для Windows, то не понимал, зачем в некоторые структуры включаются поля с их размерами. Забыв о мудром совете Авраама Линкольна, я высказался на эту тему в одной из ранних статей и был справедливо наказан. Впрочем, если бы все прислушались к совету Линкольна, никто бы не писал книг.
Поля biWidth, biHeight и biBitCount определяют размеры изображения. Содержимое поля biCompression позволяет узнать, хранится ли изображение в сжатом
В поле biSizeImage хранится размер графических данных (в пикселях). Однако учтите, что это поле часто оказывается незаполненным (содержит нулевое значение). В таких случаях нам придется самостоятельно вычислять размер графических данных.
Наконец, поле biClrUsed определят количество цветов в палитре (для палитровых изображений). Как и поле biSizeImage, оно часто может быть равно нулю. Это означает, что палитра содержит максимальное количество элементов (256 для 8-битных изображений). Остальные поля структуры BITMAPINFOHEADER не представляют для нас интереса, поэтому я не стану утомлять вас их обсуждением.
Палитра в BMP-файлах хранится в виде списка структур RGBQUAD, где каждый элемент представляет отдельный цвет. Структура RGBQUAD объявляется так:
В первых трех полях хранятся цветовые RGB-составляющие. На поле rgbReserved мы не будем обращать внимания (предполагается, что оно равно нулю). Как я упоминал выше, количество структур RGBQUAD в BMP-файле определяется полем biClrUsed. Тем не менее обычно 8-битные BMP-файлы содержат 256 структур RGBQUAD. В 24-битных RGB-файлах структуры RGBQUAD отсутствуют.
Графические данные в основном представляют собой список пикселей, из которых состоит изображение. Однако каждая горизонтальная строка пикселей должна занимать блок памяти, выровненный по границе параграфа. Следовательно, если количество байт, необходимых для хранения строки пикселей, не кратно четырем, в каждую строку включается от одного до трех дополняющих байт.
При этом для работы с графическими данными BMP-файлов используется концепция шага, упоминавшаяся выше в этой главе. Отличие состоит в том, что для графических данных BMP-файлов значение шага вам придется рассчитать самостоятельно. Впрочем, это не так уж сложно, потому что шаг всегда попадает на ближайшую границу параграфа за концом блока памяти, необходимого для хранения строки пикселей.
Изображения хранятся в BMP-файлах в перевернутом виде, так что первая строка пикселей файла на самом деле является нижней строкой настоящего изображения. Чтобы восстановить нормальное изображение, мы начнем чтение файла с последней строки пикселей и будем двигаться к началу.
В наших программах
Поддержка работы с BMP-файлами в классе DirectDrawWin обеспечивается функцией CreateSurface. Существуют две версии CreateSurface: первая в качестве аргументов получает параметры поверхности, а вторая — имя BMP-файла. Вторая версия CreateSurface загружает BMP-файл, затем создает новую поверхность, параметры которой совпадают с параметрами изображения, и копирует содержимое файла на поверхность.
Функция CreateSurface требует, чтобы изображение в передаваемом BMP-файле было палитровым или беспалитровым в зависимости от текущего видеорежима. Она не станет загружать палитровые изображения на беспалитровую поверхность, и наоборот. В принципе это возможно, но непрактично. Загрузить палитровое изображение на беспалитровую поверхность довольно просто, но глупо, потому что при этом будет использоваться лишь малая часть возможностей поверхности (всего 256 цветов из 16 миллионов). С другой стороны, загрузка беспалитровых изображений на палитровую поверхность потребует программного сокращения миллионов цветов до 256-цветной палитры.
Давайте посмотрим, как реализована функция CreateSurface (см. листинг 5.1).
Листинг 5.1. Функция CreateSurface