Шаг 143 - Читаем растр с диска

Очень интересно, но в VC нет такого простого класса, который может прочитать растровую картинку с диска, скажем BMP, и вывести её на экран. Ну нет и ладно, давайте создадим. Создавайте приложение AppWizard на основе SDI c именем TestDib.

Давайте теперь создадим новый класс через меню Insert -> New Class и имя ему дадим CDib. Вас спросят о его типе, давайте Generic Class. Вот каким он станет.

class CDib  
{
public:
	CDib();
	virtual ~CDib();
};

Давайте изменим его так, чтобы в конструктор передавали имя файла и при создании объекта класса сразу создавался файл.

class CDib  
{
public:
	CDib(CString filename);
	virtual ~CDib();
	void LoadFile(CString filename);
};

Создаем код конструктора:

CDib::CDib(CString filename)
{
	LoadFile(filename);
}

А теперь LoadFile код:

void CDib::LoadFile(CString filename)
{
	CFile file(filename,CFile::modeRead);
	BITMAPFILEHEADER bmf;
	file.Read((void *)&bmf,sizeof(bmf));
	if (bmf.bfType  != 0x4d42)
	{
		AfxMessageBox("Not Bmp File");
	}
	else
	{
		DWORD sizebmp=file.GetLength()-sizeof(bmf); 
		BYTE* ptrBmp = (BYTE*)GlobalAlloc(GMEM_MOVEABLE,sizebmp);
		file.Read((void*)ptrBmp,sizebmp); 
		file.Close(); 
		lpInfo=(LPBITMAPINFO)ptrBmp;
	}
}

Мы добавили описание переменной в класс CDib:

class CDib  
{
public:
	LPBITMAPINFO lpInfo;
	........
};

И код деструтора для уничтожения выделенной памяти.

CDib::~CDib()
{
	GlobalFree(lpInfo);
}

Это пока только болванка, но в следующих шагам мы её расширим до необходимого рабочего примера. Как видите самое интересное это функция LoadFile. Для начала мы открываем файл используя класс CFile и передавая в конструктор имя файла для открытия. Открываем его для чтения. Дальше мы зачитываем заголовок файла в структуру BITMAPFILEHEADER. Первое, что мы проверим это то, что этот файл именно BMP. Если Вы откроете файл BMP в текстовом редакторе, то увидите, что он начитается с BM, что гарантирует вроде как, что это именно то.

143.gif (3089 b)

Эта информация будет находится в поле bfType структуры. Вот это мы и проверяем. После этого мы можем расчитать память отняв от размера файла размер заголовка. Выделить память и прочитать туда файл. После чего файл закрываем. Для сохранения указателя на файл мы завели новую переменную и присвоили её значения выделенной памяти. Кроме этого добавили в деструктор освобождение памяти при закрытии объекта класса.


Загрузить проект | Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем - 11.03.2000