Рисование DIB
Если отображаемый bmp-файл содержит таблицу цветов, и на предыдущем этапе была создана палитра, ее следует выбрать в контекст отображения и реализовать:
hOldPal = SelectPalette(hdc, hPal, FALSE); RealizePalette(hdc);
После этого вы можете нарисовать DIB одним из двух способов.
Первый способ рисования заключается в предварительном преобразовании изображения DIB в изображение DDB с последующим рисованием изображения DDB. Вы уже умеете рисовать изображение DDB, для этого его следует выбрать в специально созданный контекст памяти и затем отобразить функцией BitBlt или StretchBlt.
Для преобразования DIB в DDB вы должны использовать функцию SetDIBits :
int WINAPI SetDIBits( HDC hdc, // контекст отображения HBITMAP hbmp, // изображение DDB UINT uStartScan, // номер первой строки UINT uScanLines, // количество строк const void FAR* lpvBits, // биты изображения BITMAPINFO FAR* lpbmi, // заголовок изображения UINT fuColorUse); // содержимое таблицы цветов
Параметр hdc должен содержать идентификатор контекста отображения, в котором будет отображаться полученное изображение DDB.
Через параметр hbmp следует передать идентификатор битового изображения DDB, совместимого с контекстом hdc. Его можно создать при помощи функции CreateCompatibleBitmap. После преобразования это изображение можно будет использовать для рисования функциями BitBlt или StretchBlt.
Параметр uStartScan задает номер строки сканирования битового изображения, начиная с которого будет выполняться преобразование. Если вам нужно нарисовать все изображение целиком, для этого параметра следует задать значение0.
Параметр uScanLines определяет количество строк сканирования, участвующих в преобразовании. Если нужно преобразовать все изображение, для этого параметра следует указать высоту изображения, взятую из заголовка BITMAPINFOHEADER.
Через параметр lpvBits следует передать указатель на область памяти, содержащую биты изображения в формате DIB.
В процессе преобразования функция SetDIBits использует заголовок bmp-файла BITMAPINFO, указатель на который следует передать через параметр lpbmi.
Последний параметр fuColorUse указывает функции на содержимое таблицы цветов, которая расположена сразу после структуры BITMAPINFOHEADER. Возможны два значения - DIB_RGB_COLORS и DIB_PAL_COLORS.
Если указано значение DIB_RGB_COLORS , таблица цветов содержит RGB-цвета, которые можно использовать для создания палитры. Если же указано значение DIB_PAL_COLORS , таблица цветов содержит 16-битовые ссылки на элементы системной палитры.
Если вы загрузили bmp-файл в память, таблица цветов обычно содержит именно RGB-цвета, поэтому для преобразования и последующего рисования изображения вы должны указать значение DIB_RGB_COLORS.
Возвращаемое функцией SetDIBits значение равно количеству преобразованных строк сканирования или нулю при ошибке.
Поясним процесс рисования на простом примере.
Пусть мы загрузили изображение DIB с шириной wWidth и высотой wHeight. Создаем изображение DDB, совместимое с контекстом отображения hdc и имеющее те же размеры. Для этого воспользуемся функцией CreateCompatibleBitmap :
hbmp = CreateCompatibleBitmap(hdc, wWidth, wHeight);
Создадим также контекст памяти, совместимый с контекстом отображения:
hMemDC = CreateCompatibleDC(hdc);
Далее вызываем функцию SetDIBits, которая преобразует биты изображения DIB и запишет их в созданное нами изображение DDB с идентификатором hbmp:
SetDIBits(hdc, hbmp, 0, wHeight, lpDibBits, (LPBITMAPINFO)lpih, DIB_RGB_COLORS);
Теперь нам нужно нарисовать полученное изображение DDB. Для этого выбираем его в контекст памяти и переносим в контекст отображения, например, функцией BitBlt:
hbmp = (HBITMAP)SelectObject(hMemDC, hbmp); BitBlt(hdc, x, y, wWidth, wHeight, hMemDC, 0, 0, SRCCOPY);
Все! Изображение нарисовано. Теперь можно удалить контекст памяти, не забыв перед этим выбрать в него старое битовое изображение (размером 1х1 пиксел):
DeleteObject(SelectObject(hMemDC, hbmp)); DeleteDC(hMemDC);
Второй способ нарисовать DIB немного проще:
StretchDIBits(hdc, x, y, wWidth, wHeight, 0, 0, wWidth, wHeight, lpDibBits, (LPBITMAPINFO)lpih, DIB_RGB_COLORS, SRCCOPY);
Прототип функции StretchDIBits выглядит несколько громоздко, однако эта функция дополнительно позволяет масштабировать рисуемое изображение. Функция имеет параметры, аналогичные параметрам функций StretchBlt и SetDIBits:
BOOL WINAPI StretchDIBits( HDC hdc, // контекст для рисования int nXDest, // x-координата верхнего левого угла // области рисования int nYDest, // y-координата верхнего левого угла // области рисования int nWidthDest, // новая ширина изображения int nHeightDest, // новая высота изображения int nXSrc, // x-координата верхнего левого угла // исходной области int nYSrc, // y-координата верхнего левого угла // исходной области int nWidthSrc, // ширина исходного изображения int nHeightSrc, // высота исходного изображения const void FAR* lpvBits, // биты изображения BITMAPINFO FAR* lpbmi, // заголовок изображения UINT fuColorUse, // содержимое таблицы цветов DWORD dwRop); // код растровой операции
Возвращаемое значение равно количеству преобразованных строк сканирования или нулю при ошибке.