利用MFC旋轉BMP格式圖片

      最近工作中利用MFC實現圖片旋轉的任務,發現網上這個資料比較少,也比較雜。最終自己也是看了好多代碼後,將代碼融合了一下,最終能夠滿足自己的使用要求。

1.旋轉函數

//hBitmap:要旋轉位圖的句柄
//radians   : 旋轉的角度(弧度)
//clrBack   :旋轉時的背景顏色
//旋轉圖片函數
HBITMAP GetRotatedBitmap(HBITMAP hBitmap, float radians, COLORREF clrBack)
{
	// Create a memory DC compatible with the display
	CDC sourceDC, destDC;
	sourceDC.CreateCompatibleDC(NULL);
	destDC.CreateCompatibleDC(NULL);

	// Get logical coordinates
	BITMAP bm;
	::GetObject(hBitmap, sizeof(bm), &bm);
	float cosine = (float)cos(radians);
	float sine = (float)sin(radians);
	int w = bm.bmWidth;
	int h = bm.bmHeight;
	// Create a bitmap to hold the result
	HBITMAP hbmResult = ::CreateCompatibleBitmap(CClientDC(NULL), w, h);
	HBITMAP hbmOldSource = (HBITMAP)::SelectObject(sourceDC.m_hDC, hBitmap);
	HBITMAP hbmOldDest = (HBITMAP)::SelectObject(destDC.m_hDC, hbmResult);
	// Draw the background color before we change mapping mode
	HBRUSH hbrBack = CreateSolidBrush(clrBack);
	HBRUSH hbrOld = (HBRUSH)::SelectObject(destDC.m_hDC, hbrBack);
	destDC.PatBlt(0, 0, w, h, PATCOPY);
	::DeleteObject(::SelectObject(destDC.m_hDC, hbrOld));

	// We will use world transform to rotate the bitmap
	SetGraphicsMode(destDC.m_hDC, GM_ADVANCED);
	XFORM xform;
	xform.eM11 = cosine;
	xform.eM12 = sine;
	xform.eM21 = -sine;
	xform.eM22 = cosine;
	xform.eDx = (float)(150 - cosine*150 + sine*150);
	xform.eDy = (float)(150 - cosine*150- sine*150);

	SetWorldTransform(destDC.m_hDC, &xform);
	// Now do the actual rotating - a pixel at a time
	destDC.BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &sourceDC, 0, 0, SRCCOPY);

	// Restore DCs
	::SelectObject(sourceDC.m_hDC, hbmOldSource);
	::SelectObject(destDC.m_hDC, hbmOldDest);
	return hbmResult;
}

其中:
1.xform.eDx = (float)(150 - cosine*150 + sine*150); xform.eDy = (float)(150 - cosine*150- sine*150);中的數字(150,150)指的是整個旋轉過程中的旋轉中心。
2.用於旋轉的核心函數是:SetWorldTransform。
函數原型:BOOL SetWorldTransform(HDChdc, CONST XFORM*lpXform );
hdc:指向設備環境的句柄。
lpxform:指向XFORM結構的指針,此結構含有轉換數據。XFORM中的各項參數可根據二維旋轉矩陣可輕鬆得到。

2.顯示函數

//angle:旋轉的角度
//顯示函數
RotatePicture(int angle)
{
        CBitmap bitmap;                           // CBitmap對象,用於加載位圖 
		HBITMAP hBitmap1, hBitmap2;    // 保存CBitmap加載的位圖的句柄
		CDC *pDC = this->GetDC();
		//創建一個內存中的顯示設備
		CDC MemDc;
		if (!MemDc.CreateCompatibleDC(NULL))//創建內存設備環境
			return;
		//設定旋轉圖片周圍的背景色
		COLORREF clrBack = RGB(0, 255,0);
		float rad = 3.1415926 *angle / 180;
		//加載位圖
		hBitmap1 = (HBITMAP)::LoadBitmapW(AfxGetInstanceHandle(), MAKEINTRESOURCEW(IDB_BITMAP3));
		//旋轉位圖
		hBitmap2 = PictureRotate.GetRotatedBitmapNT1(hBitmap1, rad, clrBack);
		bitmap.Attach(hBitmap2); //關聯位圖對象
		
		MemDc.SelectObject(&bitmap); //選取CBitmap對象
		pDC->BitBlt(0, 0, 600, 600, &MemDc, 0, 0, SRCCOPY); //顯示
		bitmap.DeleteObject();
		DeleteObject(hBitmap1);
		DeleteObject(hBitmap2);
		MemDc.DeleteDC();
		ReleaseDC(pDC);
		}

其中:
CBitmap、CDC、HBITMAP這些類產生的對象在使用完後都儘可能的釋放或刪除掉。

發佈了14 篇原創文章 · 獲贊 19 · 訪問量 3918
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章