Вывод растровых изображений на экран

Загрузка данных из BMP файла

Чтобы изображение загрузить с диска в оперативную память и получить дескриптор изображения (типа HBITMAP), предназначены функции LoadBitmap() и LoadImage(). Так, например, из файла с расширением.bmp изображение можно прочитать при помощи функции LoadImage ():

HBITMAP Bit=(HBITMAP)LoadImage(NULL, char* Filename,

IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE |LR_CREATEDIBSECTION)

Значение NULL первого параметра указывает, что картинка вводится из файла. При получении изображения из ресурса в первом параметре указывается дескриптор приложения. Во втором параметре задается имя файла или идентификатор ресурса. Третий параметр задает тип изображения и может принимать значения IMAGE_BITMAP, IMAGE_CURSOR, IMAGEICON. Четвертый и пятый параметры, которые указывают размеры изображения, при вводе битовой карты задаются нулями, так как эта информация имеется в заголовке BMP-файла. Шестой параметр содержит сочетание флагов. В частности, флаг LR_LOADFROMFILE указывает, что изображение вводится из файла. При задании флага LR_CREATEDIBSECTION создается аппаратно-независимое, а при его отсутствии — аппаратно-зависимое растровое изображение. Ниже приводится код функции для загрузки битовой карты, которая получает путь к файлу FileName и тип растра Туре. Нулевое значение будет означать, что используется тип DIB, а единичное значение будет применяться для типа DDB.

HBITMAP LoadPict(char *FileName, int Type)

{

if(Type)

return LoadImage(NULL, FileName,

IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

else return Loadlmage(NULL, FileName, IMAGE_BITMAP, 0, 0,

LR_LOADFROMFILE|LR_CREATEDIBSECTION);

}

Функция Load Image () позволяет загружать из ресурса битовую карту, курсор или пиктограмму, но для этого более удобны простые специализированные функции LoadBitmap(), LoadCursor(), LoadIcon().

Рассмотрим пример функции для отображения рисунка формата bmp в окне Windows.

int ShowBitMap (HWND hWnd, HBITMAP hBit, int x, int y)

// Функция отображает рисунок в заданной позиции окна

// hWnd - дискриптор окна, куда выводится изображение

// hBit - дискриптор рисунка

// (x,y) - координаты левого верхнего угла изображения в окне вывода

{

BITMAP BitMap;

//В структуру BitMap считываются параметры картинки

GetObject(hBit,sizeof(BITMAP),&BitMap);

// Из ее полей bmHeight и bmWidth получаем размеры для копирования

int Height=BitMap.bmHeight;

int Width=BitMap.bmWidth;

//Получаем контекст изображения

HDC hdc = GetDC(hWnd);

//Создаем контекст памяти

HDC hdcMem=CreateCompatibleDC(hdc);

//В созданный контекст памяти заносим дискриптор битовой карты

HBITMAP OldBitmap=(HBITMAP)SelectObject(hdcMem,hBit);

///////////////////////////////////////////////////////////////////////////////////////////////////////////

//Если в исходном тексте программы есть строка

//#include <windowsx.h>,то дескриптор hBit можно включить в контекст

// при помощи инструкции:

//HBITMAP OldBitmap=SelectBitmap(hdcMem,hBit);

///////////////////////////////////////////////////////////////////////////////////////////////////////////

//Контекст hdcMem можно использовать для рисования средствами GDI -

//создаваемое изображение с учетом заданной растровой операции наносится

//на включенную в контекст картинку.

//В окно, с которым связан контекст изображения hdc, картинка переносится

//при помощи функции копирования:

BitBlt (hdc,x,y,Width,Height,hdcMem,0,0,SRCCOPY); //PATCOPY

//После копирования уничтожаются контексты памяти и изображения

SelectObject(hdcMem,OldBitmap);

//SelectBitmap(hdcMem,OldBitmap);

ReleaseDC(hWnd,hdc);

DeleteDC(hdcMem);

return 0;

}

Рассмотрим пример функции для сохранения в файле на диске рабочей области окна в формате bmp.

int ClientToBmp (HWND hWnd, char *Name)

// Сохранение рабочей области окна в файле Name.bmp

// hWnd - дискриптор окна, рабочая область которого сохраняется

// Name - имя файла для сохранения

{

BITMAPFILEHEADER bmfHdr;

BITMAPINFOHEADER bi;

RECT r;

int BitToPixel=16; //Устанавливаем цветовую глубину 16 бит

GetClientRect(hWnd,&r); //Узнаем размер рабочей области

HDC hdc = GetDC(hWnd);

HDC hdcMem=CreateCompatibleDC(hdc);

//Создалем битовую карту BitMap по размеру рабочей области окна

//Битовая карта создается на основе контекста устройства hdc, поэтому

//она хранит изображение DDB-формата (а не DIB). Именно поэтому нельзя

//использовать функцию WriteDIBC()

HBITMAP BitMap = CreateCompatibleBitmap(hdc, r.right,r.bottom);

HBITMAP OldBitmap = (HBITMAP)SelectObject(hdcMem, BitMap);

BitBlt(hdcMem, 0, 0, r.right, r.bottom, hdc, 0, 0, SRCCOPY);

BitMap = (HBITMAP)SelectObject(hdcMem,OldBitmap);

ZeroMemory(&bi,sizeof(BITMAPINFOHEADER)); //Это аналог функции

// memset(), который заполняет заголовок нулями.

bi.biSize = sizeof(BITMAPINFOHEADER);

bi.biWidth = r.right;

bi.biHeight = r.bottom;

bi.biPlanes = 1;

bi.biBitCount = BitToPixel; //в примерах режим 16 бит тоже сохраняется,

//как 24- это DIB, но 8 бит на пиксел работать не будут – не записаны после

// заголовка элементы палитры

//Для вычисления размера изображения в байтах мы увеличиваем значение

//г.right * BitToPixel/8 байт на строку до значения, кратного четырем. Это

//вычисление может выполнить и функция GetDIBits() (см. MSDN).

bi.biSizeImage = (r.right * BitToPixel+31)/32*4 * r.bottom;

DWORD dwWritten; //Количество записанных файлов

//Открываем файл

HANDLE fh = CreateFile(Name, GENERIC_WRITE, 0, NULL,

CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL |

FILE_FLAG_SEQUENTIAL_SCAN, NULL);

if (fh == INVALID_HANDLE_VALUE) return 2;

bmfHdr.bfType = ('M'<<8)|'B'; //Заполняем дисковый заголовок

bmfHdr.bfSize = bi.biSizeImage + sizeof(bmfHdr)+bi.biSize; //Размер файла

bmfHdr.bfReserved1 = bmfHdr.bfReserved2 = 0;

bmfHdr.bfOffBits = sizeof(bmfHdr) + bi.biSize; // Смещение до начала данных

//Запись заголовка в файл

WriteFile(fh, (LPSTR)&bmfHdr, sizeof(bmfHdr), &dwWritten, NULL);

// Запись в файл загружаемого заголовка

WriteFile(fh, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwWritten,

NULL);

//Выделяем место в памяти для того,чтобы функция GetDIBits()перенесла

//туда коды цвета в DIB-формате.

char *lp=(char *) GlobalAlloc(GMEM_FIXED, bi.biSizeImage);

// Из карты BitMap строки с нулевой по bi.biHeight функция пересылает

// в массив lp по формату bi (беспалитровый формат)

int err=GetDIBits(hdc, BitMap,0,(UINT)r.bottom, lp,(LPBITMAPINFO)&bi,

DIB_RGB_COLORS);

//Запись изображения на диск

WriteFile(fh, lp, bi.biSizeImage, &dwWritten, NULL);

//Освобождение памяти и закрытие файла

GlobalFree(GlobalHandle(lp));

CloseHandle(fh);

ReleaseDC(hWnd,hdc);

DeleteDC(hdcMem);

if (dwWritten == 0) return 2;

return 0;

}


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: