C++ winapi中的位图旋转

C++ winapi中的位图旋转,c++,winapi,bitmap,C++,Winapi,Bitmap,我有一个位图(一个小精灵),我必须以一定的角度旋转。我找到了这段代码,并尝试将其应用于我的应用程序,但它似乎不起作用。精灵根本不旋转,而是移动了一点 以下是功能代码: void Sprite::Rotate(float radians, const char* szImageFile) { // Create a memory DC compatible with the display HDC sourceDC, destDC; sourceDC = CreateCompatibleD

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

以下是功能代码:

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编程的初学者。


编辑:这里是我得到代码的地方:。我不得不改变一下,但我不认为是因为这个,我只是把CDC换成了HDC。我推荐的一件重要的事情是(0,0)坐标。因为代码中的图像被认为是在角落里,但在我的应用程序中,它位于精灵的中心。即使这是一个问题,我认为这是一个计算位图新尺寸的问题,我看不到与旋转的联系。

如果位图在移动,我认为worldtransform和blit都起作用。
是由于转换的eDx/eDy参数而移动的量吗?

仅仅对“旋转”示例中的值进行硬编码是否会产生差异?正弦以相反的符号传递。因此,它可能只是忽略了变换的旋转部分,只进行了平移。

请检查SetWorldTransform是否成功或失败。也就是说,返回TRUE或FALSE。这没有任何区别,即使我输入了示例中的值。在XFORM结构的任何值上,它都以相同的方向和距离移动。当我改变角度(我传递给函数的弧度数)时,方向会改变。这一定是DCs或bitblt本身的问题。试着把这些小东西换成一个Drawrect也许?还是没什么。我试图更改
sourceDC=CreateCompatibleDC(mpbackuffer->getDC());destDC=CreateCompatibleDC(空)
to
sourceDC=CreateCompatibleDC(mpbackuffer->getDC());destDC=CreateCompatibleDC(空)和它做同样的事情。我有一个从位图DC到一个单独的窗口DC旋转的BitBlt。如果直接从位图将代码加载到后缓冲区dc,它是否有效?是的,它有效,一位朋友使用DIB数组实现了这一点。我认为我的问题在于HDC的声明和操作。