1. 程式人生 > >VS2010 用CxImage讀入各種圖片格式後在記憶體中轉換為HBITMAP點陣圖

VS2010 用CxImage讀入各種圖片格式後在記憶體中轉換為HBITMAP點陣圖

最近自學遊戲引擎設計,希望將各種圖片格式讀入記憶體後轉為HBITMAP處理,四處搜尋無果,最終參考以下兩篇博文自己搞定之

http://blog.csdn.net/wu_xiangwei/article/details/5096529

http://www.cnblogs.com/xiangism/archive/2012/10/16/2725692.html

廢話不多說,先上關鍵程式碼

//將CxImage轉為點陣圖
HBITMAP Draw::ChangeCxImageToBMP(HDC hDC,CxImage* cximage)
{
	//建立HBITMAP
	HBITMAP BMP=CreateCompatibleBitmap(hDC,cximage->GetWidth(),cximage->GetHeight());
	BITMAP bm;	
	GetObject(BMP,sizeof(BITMAP),&bm);
	int pb=bm.bmBitsPixel/8;	//獲取點陣圖位數
	int BytesPerLineOut = (bm.bmWidth*pb + 3) / 4 * 4;	//計算每行畫素的資料長度
	BYTE *pxd = new unsigned char[bm.bmHeight*BytesPerLineOut]; //宣告暫存陣列

	if(cximage->GetBpp()>=16)
	{
		//直接獲取畫素資料
		int pbx=cximage->GetBpp()/8;	//獲取CxImage圖片的位數
		int BytesPerLine = (bm.bmWidth*pbx + 3) / 4 * 4;	//計算CxImage每行畫素的資料長度
		BYTE *pDib = cximage->GetBits();	//獲取CxImage圖片的畫素資料

		for (int i = 0; i < bm.bmHeight; i++) 
		{ 
			for (int j = 0; j < bm.bmWidth; j++) 
			{ 
				int srcRGB_B=(bm.bmHeight-1-i)*BytesPerLine+j*pbx;
				int desRGB_B=i*bm.bmWidthBytes+j*pb;

				pxd[desRGB_B] = pDib[srcRGB_B];
				pxd[desRGB_B+1] = pDib[srcRGB_B+1];
				pxd[desRGB_B+2] = pDib[srcRGB_B+2];
			} 
		}
	}
	else
	{
		//通過調色盤獲取畫素資料
		for (int i = 0; i < bm.bmHeight; i++) 
		{ 
			for (int j = 0; j < bm.bmWidth; j++) 
			{ 
				RGBQUAD srcRGB_B=cximage->GetPixelColor(j,bm.bmHeight-1-i);
				int desRGB_B=i*bm.bmWidthBytes+j*pb;

				pxd[desRGB_B] = srcRGB_B.rgbBlue;
				pxd[desRGB_B+1] = srcRGB_B.rgbGreen;
				pxd[desRGB_B+2] = srcRGB_B.rgbRed;
			} 
		}
	}

	SetBitmapBits(BMP,bm.bmHeight*bm.bmWidthBytes,pxd);
	delete[] pxd;

	return BMP;
}

示例程式碼下載:

http://download.csdn.net/detail/daeba/8388505

示例程式碼只測試了JPG、PNG、8位點陣圖、GIF動態圖片四種,其餘CxImage支援的圖片格式尚未測試

程式碼中包含CxImage(6.00full)的Debug與Release版靜態庫,預設工程中使用的是Debug版,想執行Release版的話,請替換掉專案中的cximage.lib檔案

關鍵程式碼在Draw.cpp檔案中

初始化程式碼在GameStart.cpp檔案的GameStart()方法中

測試繪圖程式碼在GameStart.cpp檔案的GamePaint()方法中

其餘的程式碼可以無視之