Зависимые от устройства битмапы
Обычный, зависимый от устройства битмап является простым образом видеопамяти. Его организация отражает особенности аппаратуры, на которой он должен воспроизводиться. 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; Мы поможем в написании вашей работы! |
Мы поможем в написании ваших работ!