2012-03-17 119 views
1

我有一個BitMap(一個小精靈),我必須以特定角度旋轉。我發現了這個代碼,並且試圖將它適用於我的應用程序,但它似乎不起作用。精靈根本不旋轉,而是稍微移動一點。winapi中的位圖旋轉

這裏的功能代碼:

void Sprite::Rotate(float radians, const char* szImageFile) 
{ 
    // Create a memory DC compatible with the display 
HDC sourceDC, destDC; 
sourceDC = CreateCompatibleDC(mpBackBuffer->getDC()); 
destDC = CreateCompatibleDC(mpBackBuffer->getDC()); 

// Get logical coordinates 
HBITMAP hBitmap = (HBITMAP)LoadImage(g_hInst, szImageFile, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE); 
BITMAP bm; 
::GetObject(hBitmap, sizeof(bm), &bm); 

float cosine = (float)cos(radians); 
float sine = (float)sin(radians); 

// Compute dimensions of the resulting bitmap 
// First get the coordinates of the 3 corners other than origin 
int x1 = (int)(bm.bmHeight * sine); 
int y1 = (int)(bm.bmHeight * cosine); 
int x2 = (int)(bm.bmWidth * cosine + bm.bmHeight * sine); 
int y2 = (int)(bm.bmHeight * cosine - bm.bmWidth * sine); 
int x3 = (int)(bm.bmWidth * cosine); 
int y3 = (int)(-bm.bmWidth * sine); 

int minx = min(0,min(x1, min(x2,x3))); 
int miny = min(0,min(y1, min(y2,y3))); 
int maxx = max(0,max(x1, max(x2,x3))); 
int maxy = max(0,max(y1, max(y2,y3))); 

int w = maxx - minx; 
int h = maxy - miny; 

// Create a bitmap to hold the result 
HBITMAP hbmResult = ::CreateCompatibleBitmap(mpBackBuffer->getDC(), w, h); 

HBITMAP hbmOldSource = (HBITMAP)::SelectObject(sourceDC, hBitmap); 
HBITMAP hbmOldDest = (HBITMAP)::SelectObject(destDC, hbmResult); 

// Draw the background color before we change mapping mode 
HBRUSH hbrBack = CreateSolidBrush(mcTransparentColor); 
HBRUSH hbrOld = (HBRUSH)::SelectObject(destDC, hbrBack); 
PatBlt(destDC, 0, 0, w, h, PATCOPY); 
::DeleteObject(::SelectObject(destDC, hbrOld)); 




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

SetWorldTransform(destDC, &xform); 

// Now do the actual rotating - a pixel at a time 
BitBlt(destDC, 0, 0, w, h, sourceDC, 0, 0, SRCCOPY); 
// Restore DCs 
::SelectObject(sourceDC, hbmOldSource); 
::SelectObject(destDC, hbmOldDest); 

BITMAP btm; 
::GetObject(hbmResult, sizeof(mImageBM), &mImageBM); 

} 

我想不通爲什麼它不旋轉圖像,而是它移動它。此外,如果你知道另一種方法來做到這一點,我願意提供建議,但請記住,我只能使用winapi,沒有額外的庫,我是Windows編程的初學者。

編輯:這裏是我得到的代碼:http://www.codeguru.com/cpp/g-m/bitmap/specialeffects/article.php/c1743/。我不得不改變它,但我不認爲這是因爲這個原因,我只是將CDC改爲HDC。我忽略的一件重要事情是(0,0)座標。因爲代碼中的圖像被認爲是在角落,但在我的應用程序中,它位於精靈的中心。即使這是一個問題,我認爲這是一個計算位圖的新維度的問題,我沒有看到與旋轉的連接。

+0

請你檢查SetWorldTransform是成功還是失敗。即,返回TRUE或FALSE。 – Robinson 2012-03-17 23:13:22

+0

它返回TRUE。 – Andrei 2012-03-17 23:17:05

回答

2

如果位圖在移動,在我看來世界變換和blit都起作用了。
由於變換的eDx/eDy參數,它移動的量是多少?
只是硬編碼「旋轉」示例中的值here有什麼不同?正弦通過相反的符號。所以它可能只是忽略了轉換的旋轉部分,只做了翻譯。

+0

即使我把示例中的值放在一起,它也沒有什麼區別。在XFORM結構的任何值處,它都以相同的方向和相同的距離移動。當我改變角度(我傳遞給函數的弧度數)時,方向改變。 – Andrei 2012-03-17 23:34:22

+0

必須是DC或bitblt本身的問題。爲了Drawrect而改變bitblit? – 2012-03-17 23:45:19

+0

什麼都沒有。我試着改變 'sourceDC = CreateCompatibleDC(mpBackBuffer-> getDC());我們可以通過下面的例子來說明如何使用DCDC的方法來創建一個DCDC。 destDC = CreateCompatibleDC(NULL);' 並且它做同樣的事情。 – Andrei 2012-03-18 00:02:12