1. 程式人生 > >VC/MFC讀取BMP檔案並顯示

VC/MFC讀取BMP檔案並顯示

自己寫過的程式碼,留作儲存,以後不會忘了

先宣告幾個變數

	BYTE * pBMPDataBuf;//BMP資料buf
	BITMAPFILEHEADER BmpHeader;//BMP影象檔案頭
	BITMAPINFO BmpInfo;//BMP影象資訊結構
	RGBQUAD * pRGBQUAD;//調色盤
	DWORD dwBmpDataSize;//BMP資料區大小

在LoadBMPFile函式中讀取檔案資料
BOOL CBMPControl::LoadBmpFile(CFile& file)
{
	//讀取bmp檔案頭
	file.Read(&BmpHeader,sizeof(BITMAPFILEHEADER));
	//判斷BMP型別
	if (BmpHeader.bfType != DIB_MARKER)// 判斷是否是DIB物件
	{		
		strBMPError = "不是BMP檔案型別";
		return FALSE;
	}
	//讀取bmp資訊頭和第一個顏色表
	file.Read(&BmpInfo,sizeof(BITMAPINFO));

	int iBitNum = GetRGBQUADNum(BmpInfo.bmiHeader.biBitCount);//獲得影象位數,確定分配顏色表使用
	if (iBitNum!=0)//不是黑白,16色,256色圖片,則沒有顏色表
	{
		file.Seek(54,CFile::begin);//從檔案開始向後移動54個位元組,跳過檔案頭結構和資訊頭結構
		pRGBQUAD = new RGBQUAD[iBitNum];
		file.Read(pRGBQUAD,sizeof(RGBQUAD)*iBitNum);
	}

	//移動到BMP資料區指標
	file.Seek(BmpHeader.bfOffBits,CFile::begin);
	dwBmpDataSize = BmpInfo.bmiHeader.biSizeImage;//影象資料大小
	pBMPDataBuf = new BYTE[dwBmpDataSize];
	file.Read(pBMPDataBuf,BmpInfo.bmiHeader.biSizeImage);
	return TRUE;
}
#define DIB_MARKER   ((WORD) ('M' << 8) | 'B')
只是定義的一個巨集,判斷是否為BMP格式的檔案,具體詳細的自己搜尋吧 GetRGBQUADNum這個函式只是根據位數返回顏色數,24點陣圖和32點陣圖是沒有顏色表的
int XXXXXX::GetRGBQUADNum(int ibit)
{
	int iNum=0;
	switch(ibit)
	{
		case 1:
			iNum = 2;
			break;
		case 4:
			iNum = 16;
			break;
		case 8:
			iNum = 256;
			break;
		default:
			iNum = 0;
	}
	return iNum;
}

好了,讀到了資料,就顯示吧,我只是簡單的進行了自動拉伸顯示,如果想用其他顯示方式,自己再研究吧
BOOL XXXXXXX::DrawBMPAutoRange(CDC *pDC,CRect*rect)//繪製BMP
{
	SetStretchBltMode(pDC->m_hDC,HALFTONE);
	
	::StretchDIBits(pDC->m_hDC,								// 裝置環境控制代碼
		0,                 //目標X座標
		0,                  // 目標Y座標
		rect->Width(),            // 目標寬度
		rect->Height(),           // 目標高度
		0,                // 源X座標
		0,                 // 源Y座標
		BmpInfo.bmiHeader.biWidth,           // 源寬度
		BmpInfo.bmiHeader.biHeight,          // 源高度
		pBMPDataBuf,                      // 指向dib畫素的指標
		&BmpInfo,         // 指向點陣圖資訊結構的指標
		DIB_RGB_COLORS,                 // 使用的顏色數目
		//DIB_PAL_COLORS,
		SRCCOPY);                       // 光柵操作型別	
	/*SetDIBitsToDevice*/
	return TRUE;
}