1. 程式人生 > >C++將HBITMAP儲存為bmp圖片

C++將HBITMAP儲存為bmp圖片

BOOL CBMP2ArrayMultiplyDlg::SaveBitmapToFile(HBITMAP   hBitmap, CString szfilename)
{
	HDC     hDC;         
	//當前解析度下每象素所佔位元組數          
	int     iBits;         
	//點陣圖中每象素所佔位元組數          
	WORD     wBitCount;         
	//定義調色盤大小,     點陣圖中畫素位元組大小     ,點陣圖檔案大小     ,     寫入檔案位元組數              
	DWORD     dwPaletteSize=0,   dwBmBitsSize=0,   dwDIBSize=0,   dwWritten=0;             
	//點陣圖屬性結構              
	BITMAP     Bitmap;                 
	//點陣圖檔案頭結構          
	BITMAPFILEHEADER     bmfHdr;                 
	//點陣圖資訊頭結構              
	BITMAPINFOHEADER     bi;                 
	//指向點陣圖資訊頭結構                  
	LPBITMAPINFOHEADER     lpbi;                 
	//定義檔案,分配記憶體控制代碼,調色盤控制代碼              
	HANDLE     fh,   hDib,   hPal,hOldPal=NULL;             

	//計算點陣圖檔案每個畫素所佔位元組數              
	hDC  = CreateDC("DISPLAY",   NULL,   NULL,   NULL);         
	iBits  = GetDeviceCaps(hDC,   BITSPIXEL)     *     GetDeviceCaps(hDC,   PLANES);             
	DeleteDC(hDC);             
	if(iBits <=  1)                                                   
		wBitCount = 1;             
	else  if(iBits <=  4)                               
		wBitCount  = 4;             
	else if(iBits <=  8)                               
		wBitCount  = 8;             
	else                                                                                                                               
		wBitCount  = 24;

	GetObject(hBitmap,   sizeof(Bitmap),   (LPSTR)&Bitmap);         
	bi.biSize= sizeof(BITMAPINFOHEADER);         
	bi.biWidth = Bitmap.bmWidth;         
	bi.biHeight =  Bitmap.bmHeight;         
	bi.biPlanes =  1;         
	bi.biBitCount = wBitCount;         
	bi.biCompression= BI_RGB;         
	bi.biSizeImage=0;         
	bi.biXPelsPerMeter = 0;         
	bi.biYPelsPerMeter = 0;         
	bi.biClrImportant = 0;         
	bi.biClrUsed =  0;         

	dwBmBitsSize  = ((Bitmap.bmWidth *wBitCount+31) / 32)*4* Bitmap.bmHeight;         

	//為點陣圖內容分配記憶體              
	hDib  = GlobalAlloc(GHND,dwBmBitsSize+dwPaletteSize+sizeof(BITMAPINFOHEADER));             
	lpbi  = (LPBITMAPINFOHEADER)GlobalLock(hDib);             
	*lpbi  = bi;             

	//     處理調色盤                  
	hPal  = GetStockObject(DEFAULT_PALETTE);             
	if (hPal)             
	{             
		hDC  = ::GetDC(NULL);             
		hOldPal = ::SelectPalette(hDC,(HPALETTE)hPal, FALSE);             
		RealizePalette(hDC);             
	}         

	//     獲取該調色盤下新的畫素值              
	GetDIBits(hDC,hBitmap, 0,(UINT)Bitmap.bmHeight,  
		(LPSTR)lpbi+ sizeof(BITMAPINFOHEADER)+dwPaletteSize,   
		(BITMAPINFO *)lpbi, DIB_RGB_COLORS);             

	//恢復調色盤                  
	if (hOldPal)             
	{             
		::SelectPalette(hDC,   (HPALETTE)hOldPal,   TRUE);             
		RealizePalette(hDC);             
		::ReleaseDC(NULL,   hDC);             
	}             

	//建立點陣圖檔案                  
	fh  = CreateFile(szfilename,   GENERIC_WRITE,0,   NULL,   CREATE_ALWAYS,           
		FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,   NULL);             

	if (fh     ==  INVALID_HANDLE_VALUE)         return     FALSE;             

	//     設定點陣圖檔案頭              
	bmfHdr.bfType  = 0x4D42;     //     "BM"              
	dwDIBSize  = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+dwPaletteSize+dwBmBitsSize;                 
	bmfHdr.bfSize  = dwDIBSize;             
	bmfHdr.bfReserved1  = 0;             
	bmfHdr.bfReserved2  = 0;             
	bmfHdr.bfOffBits  = (DWORD)sizeof(BITMAPFILEHEADER)+(DWORD)sizeof(BITMAPINFOHEADER)+dwPaletteSize;             
	//     寫入點陣圖檔案頭              
	WriteFile(fh,   (LPSTR)&bmfHdr,   sizeof(BITMAPFILEHEADER),   &dwWritten,   NULL);             
	//     寫入點陣圖檔案其餘內容              
	WriteFile(fh,   (LPSTR)lpbi,   dwDIBSize,   &dwWritten,   NULL);             
	//清除                  
	GlobalUnlock(hDib);             
	GlobalFree(hDib);             
	CloseHandle(fh);             

	return     TRUE;         

}