Поворот растрового изображения в winapi - PullRequest
1 голос
/ 18 марта 2012

У меня есть 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/.Мне пришлось немного изменить его, но я не думаю, что это из-за этого, я только изменил CDC на HDC.Одной важной вещью, которую я пропустил, является координата (0, 0).изображение в этом коде рассматривается в углу, но в моем приложении оно находится в центре спрайта.Даже если это проблема, я думаю, что это проблема вычисления новых размеров растрового изображения, я не вижу связи с вращением.

1 Ответ

2 голосов
/ 18 марта 2012

Если растровое изображение движется, мне кажется, что преобразование мира и блиц сработали.
Это величина, которую он перемещает из-за параметров eDx / eDy преобразования?
Имеет ли значение только жесткое кодирование значений из примера «вращения» здесь ? Синусы передаются с противоположным знаком. Так что, возможно, он просто проигнорировал вращающуюся часть преобразования и сделал только перевод.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...