Зависимые от устройства битмапы



 

Обычный, зависимый от устройства битмап является простым образом видеопамяти. Его организация отражает особенности аппаратуры, на которой он должен воспроизводиться. DDB в приложении представляется как объект GDI; аналогично описанию перьев или кистей DDB описывается с помощью специальной структуры (BITMAP) и доступен посредством хендла этого объекта типа (HBITMAP).

typedef struct tagBITMAP {

int bmType;

int bmWidth;

int bmHeight;

int bmWidthBytes;

BYTE bmPlanes;

BYTE bmBitsPixel;

LPSTR bmBits;

} BITMAP;

Поле bmType должно быть 0, поля bmWidth и bmHeight определяют размеры изображения, bmPlanes и bmBitsPixel используются для указания способа кодирования информации о цвете точки и для указания максимального количества цветов.

Использование двух полей bmPlanes и bmBitsPixel связано с особенностями хранения цветного изображения разными видеоадаптерами. Например, CGA, IBM 8514 или SVGA в некоторых режимах для задания цвета пикселя отводят несколько последовательных бит памяти (CGA — 2 бита, IBM — 8 бит, SVGA — до 32 бит на каждый пиксель). А адаптеры типа EGA или VGA (и, конечно, в некоторых режимах SVGA) содержат несколько так называемых битовых плоскостей, или планов (planes). В каждом плане одному пикселю соответствует только один бит, а цвет задается комбинацией бит в разных планах. Поле bmPlanes структуры BITMAP определяет количество цветовых планов, а поле bmBitsPixel — количество последовательных бит, отведенных для задания цвета пикселя а одном плане. По крайней мере один из этих параметров равен 1 (или оба — для монохромных битмапов).

Изображение в битмапе хранится разделенным на строки растра (scan line). Длина каждой строки округляется в большую сторону до ближайшей четной границы (кратна 2 байтам) и задается полем bmWidthBytes. Для вычисления длины строки надо произведение bmWidth * bmBitsPixel разделить на 8 и округлить в сторону завышения до ближайшего четного числа.

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

Поле bmBits теоретически должно указывать на собственно данные битмапа (массив строк растра). Однако оно используется далеко не всегда — вы его можете задавать, но когда информацию о битмапе вам возвращает система (функция GetObject), то это поле не инициализируется — для получения данных битмапа существует специальная функция — GetBitmapBits.

 

Создание зависимого от устройства битмапа

 

Создание зависимых от устройства битмапов — случай сравнительно редкий; обычно битмапы готовятся специальным графическим редактором и позже загружаются в память либо из файла, либо из ресурсов приложения. В связи с этим предлагаемый здесь материал нужен, в основном, для более близкого «фамильярного» знакомства с DDB; на практике использоваться этот материал будет редко. Предположим, что мы хотим создать битмап для использования в качестве кисти. Кисть всегда имеет размер 8x8 пикселей. Кроме того, для упрощения, мы будем предполагать, что используется монохромный битмап. Монохромный — так как изображение этого битмапа мы опишем сами, а описание цветного битмапа непосредственно в приложении — крайне неэффективное решение. Кроме того, монохромные битмапы обрабатываются несколько особым образом, так что есть повод обратить внимание на их особенности. Итак, пусть мы хотим получить следующую картинку:

 

Рисунок 16. Подготавливаемый рисунок монохромного битмапа (при использовании такого битмапа в качестве кисти мы получим "кирпичную стену").

 

Обратите внимание на нумерацию байтов и бит в байте — байты (не слова) нумеруются слева–направо, а биты в байте — справа–налево. Подготовим для этой картинки данные битмапа: так как ширина битмапа 8, количество бит на пиксель 1, то в одной строке растра должно быть 8 бит, значит ее длина 2 байта (четное число) или одно слово.

static WORD wBits[]={

0x00FF, 0x00C0, 0x00C0, 0x00C0, 0x00FF, 0x000C, 0x000C, 0x000C};

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

HBITMAP CreateBitmap (cxWidth, cyHeight, nPlanes, nBitsPixel, lpBits);

HBITMAP CreateBitmapIndirect (lpBitmap);

HBITMAP CreateCompatibleBitmap (hDC, cxWidth, cyHeight);

HBITMAP CreateDiscardableBitmap (hDC, cxWidth, cyHeight);

Функция CreateBitmap позволяет создать битмап с заданными характеристиками. В нашем случае это будет выглядеть так:

HBITMAP hBmp= CreateBitmap (8, 8, 1, 1, wBits);

Функция CreateBitmapIndirect позволяет сначала описать структуру типа BITMAP, а затем создать битмап по этой структуре. В нашем примере эту функцию можно использовать, например, таким образом:

static BITMAP stBmp= {

0, // bmType

8,8, // bmWidth, bmHeight

2, // bmWidthBytes

1,1, // bmPlanes, bmBitsPixel

NULL // bmBits};

HBITMAP hBmp= CreateBitmapIndirect (&stBmp);

SetBitmapBits (hBmp, sizeof (wBits), wBits);

Конечно, мы могли установить адрес образа (wBits) в поле bmBits и обойтись без функции SetBitmapBits но так мы рассмотрим на одну функцию больше.

В некоторых случаях мы будем создавать битмапы, которые должны быть по своим характеристикам совместимы с конкретным контекстом устройства. Для этого предназначена функция CreateCompatibleBitmap, которая создает битмап указанного размера и такой же организации, как указанный контекст устройства. Изображение при этом не задается — битмап содержит набор случайных данных. Позже вы можете воспользоваться, например, функцией SetBitmapBits для задания данных битмапа.

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

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

Независимо от способа создания, существует одна особенность в применении монохромных битмапов: при его отображении на цветном устройстве для представления точек битмапа будут использоваться не черный и белый цвета, а текущий цвет фона (для всех бит, равных 0, — обычно это белый цвет) и текущий цвет текста (для всех бит, равных 1, обычно это черный цвет). Таким образом вы можете в определенной мере управлять отображением монохромного битмапа с помощью функций SetTextColor и SetBkColor.

При необходимости вы можете узнать характеристики битмапа, используя функцию GetObject:

BITMAP stBmp;

GetObject (hBmp, sizeof (stBmp), &stBmp);

Однако эта функция не устанавливает поле bmBits структуры BITMAP. Для получения данных битмапа надо воспользоваться функцией:

LPSTR GetBitmapBits (hBitmap, dwMaxSize, lpBuffer);

Еще несколько функций могут использоваться совершенно специфичным способом:

DWORD GetBitmapDimension (hBmp);

BOOL GetBitmapDimensionEx (hBmp, lpSize);

DWORD SetBitmapDimension (hBmp, nWidth, nHeight);

BOOL SetBitmapDimensionEx (hBmp, nX, nY, lpSize);

Эти процедуры используются для задания/получения справочного размера битмапа, в единицах по 0.1 мм. Никакие иные функции GDI не используют эту информацию при работе с битмапами. Практически вы можете использовать эти размеры сами при необходимости передачи битмапов между устройствами с разной разрешающей способностью.

 


Дата добавления: 2019-02-12; просмотров: 211; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!