winapi中的位图旋转

Bitmap rotation in winapi

本文关键字:旋转 位图 winapi      更新时间:2023-10-16

我有一个BitMap(一个小精灵),我必须以一定的角度旋转。我找到了这段代码,并试图将其适应我的应用程序,但它似乎不起作用。精灵根本不旋转,而是稍微移动一点。

这是功能代码:

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/。我不得不稍微改变一下,但我不认为是因为这个,我只是把CDCs改成了HDC。我犯下的一件重要的事情是(0,0)coord。对于该代码中的图像,它被认为位于角落,但在我的应用程序中,它位于sprite的中心。即使这是个问题,我认为这是一个计算位图新维度的问题,我看不出与旋转的联系。

如果位图正在移动,在我看来,worldtransform和blit都有效
它移动的量是由于变换的eDx/eDy参数引起的吗
仅仅对"旋转"示例中的值进行硬编码是否会产生影响?sines是用相反的符号传递的。所以它可能只是忽略了变换的旋转部分,只做了平移。