Click here to Skip to main content
15,887,267 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hello every one..

I have a requirement. I have to rotate a dc that has a bitmap blitted on it. But i dont know how to do it? Below is the sample code:


////////////////////////////////////////////
HBITMAP m_hBitmapSmall;
CString m_csBitmap;
m_csBitmap = "c://Aircraft.bmp";
m_hBitmapSmall = (HBITMAP)LoadImage(NULL,m_csBitmap.GetBuffer(m_csBitmap.GetLength()),IMAGE_BITMAP,0,0,LR_LOADFROMFILE);

int iFrameWidth = 37, iFrameHeight = 37;
CBitmap* pBmp = new CBitmap();
CDC tempDC;
tempDC.CreateCompatibleDC(NULL);
tempDC.SetBkMode(TRANSPARENT);
pBmp->CreateCompatibleBitmap(&tempDC,iFrameWidth,iFrameHeight);
tempDC.SelectObject(pBmp);
CBitmap *pIconBitmap;
pIconBitmap = CBitmap::FromHandle(m_hBitmapSmall);


CDC tempIconDC;
tempIconDC.CreateCompatibleDC(NULL);
tempIconDC.SetBkMode(TRANSPARENT);
tempIconDC.SelectObject(pIconBitmap);
tempDC.PatBlt(0,0,iFrameWidth,iFrameHeight,BLACKNESS);
tempDC.BitBlt(0,0,iFrameWidth,iFrameHeight,&tempIconDC,0,0,SRCCOPY);//now u have the bitmap on tempDC, so play with it.


//rotate tempDC before final blitting
//help required here...


//blit the tempDC to final DC
pDC->BitBlt(0,0,iFrameWidth,iFrameHeight,&tempDC,0,0,SRCCOPY); //original bitmap

//////////////////////////////////////////////////

In the above code, before teh last line of blitting where tempDC is blitted to pDC (of the document view architecture), i want to rotate the tempDC according to a given angle. The Aircraft.bmp is a small 37x37 bmp of an aircraft. so when i rotate the tempDC, the aircraft will be rotated automatically, as it is already blitted to the tempDC. i have tried few methods, but the shape is shearing, which is not affordable. I cant roatate the Aircraft.bmp each time, as i load it once on the beginning and then want to rotate it as i receive an angle. can anyone help? I'll be thankful for help...
Posted

Maybe this one [^] will help you.

P.S.
Sorry for lots of revisions... my browser's behavior is strange at this moment :(
 
Share this answer
 
v7
Thanks Jast_In for your reply...

i actually implemented a code that uses SetWorldTransform, but can't get it working..
below is the code:

int iAngleInDeg = 90;
HBITMAP hBitmap;
CString m_csBitmap;
m_csBitmap = "C://Aircraft.bmp";
hBitmap = (HBITMAP)LoadImage(NULL,m_csBitmap.GetBuffer(m_csBitmap.GetLength()),IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
CDC sourceDC, destDC;
sourceDC.CreateCompatibleDC( NULL );
destDC.CreateCompatibleDC( NULL );
// Get logical coordinates
BITMAP bm;
::GetObject( hBitmap, sizeof( bm ), &bm );
float radians = radians=(2*3.1416*iAngleInDeg)/360;
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(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( RGB(0,0,0) );
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)-minx;
xform.eDy = (float)-miny;
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) ;
//now draw the rotated bitmap on final DC, i.e. pDC
pDC->BitBlt(0, 0,bm.bmWidth, bm.bmHeight, &destDC, 0, 0, SRCCOPY);

// Restore DCs
::SelectObject( sourceDC.m_hDC, hbmOldSource );
::SelectObject( destDC.m_hDC, hbmOldDest );
 
Share this answer
 
What does it mean "can't get it working"?
What happens?
 
Share this answer
 
Does your program draw your bitmap without rotating? I guess your problem now is not rotating but drawing a bitmap. Or maybe something is not clear for me
 
Share this answer
 
Thanks all of you. The solution is working fine now..

Thanks to Eugen Podsypalnikov for considering the problem and helping at each problematic step..

Thanks goes to Jast_In also for suggesting proposed solutions..

It was this code missing due to which the program was not drawing the resultant rotated bitmap:

int iSaved(cDestDC.SaveDC());
// Set Transform and copy your source DC
cDestDC.RestoreDC(iSaved);


Thank you all you guys
 
Share this answer
 
This[^] article shows how to do it.
 
Share this answer
 
Please make the following frame:
...
int iSaved(cDestDC.SaveDC());
// Set Transform and copy your source DC here
...
cDestDC.RestoreDC(iSaved);
...
// Copy the destDC to your finalDC :)
...

Now it is done correctly :)
 
Share this answer
 
v2
It works :) :

#include <math.h>
void CBmpTransDlg::OnBnClickedButton2()
{
  CWnd* pcStatic = GetDlgItem(IDC_STATIC2);
  if (pcStatic) {
    CBitmap cBmp;
    if (cBmp.LoadBitmap(IDB_BITMAP1)) {
      CClientDC cDC(pcStatic);
      CDC cMemDC;
      cMemDC.CreateCompatibleDC(&cDC);
      HGDIOBJ hOldBmp = cMemDC.SelectObject(cBmp.m_hObject);
      
      double dCurAngle  = 90;
      double dWinkel = (dCurAngle) / -180.0 * 3.1416;
      float dCos = (float) cos(dWinkel);
      float dSin = (float) sin(dWinkel);
      
      XFORM xForm = {0};
      xForm.eM11 = dCos;
      xForm.eM12 = dSin;
      xForm.eM21 = -dSin;
      xForm.eM22 = dCos;
      int iSaved = cDC.SaveDC();
      cDC.SetGraphicsMode(GM_ADVANCED);
      cDC.SetWorldTransform(&xForm);
      cDC.BitBlt(-50, 50, 100, 100, &cMemDC, 0, 0, SRCCOPY);
      cDC.RestoreDC(iSaved);
      
      cMemDC.SelectObject(hOldBmp);
    }
  }
}
 
Share this answer
 
Dear Christian Graus, thanks for your reply...

i have already visited the link you have provided.. i have observed the code and found that it can rotate a dc only in angles multiples of 90. while i want to rotate my dc in any angle from 0 to 360 degrees. When i do it, the image shears and looks bad..

Kindly help...
 
Share this answer
 
It draws nothing... The rotated bitmap lies in the destDC. destDC is a temporary DC to hold the rotated bitmap. When i blit it to the final DC (pDC) using bitblit, it draws nothing. If you are able to run the code, you will observer what i mean here.

Thanks for your concern..

Hope to reach a solution soon...
 
Share this answer
 
Well Eugen Podsypalnikov, Thanks for your reply...

By Not working, I didnt mean that SetWorldTransform and Bitblt are not working. I meant to say that my implementation is not helping me out.. In my case, the Aircraft.bmp is a 17x17 or 35x35 bmp image that is loaded in the very beginning of program.As mentioned in the case of sample code I posted earlier, a sourcedc contains this small bitmap, which is to be rotated onto a destDC and then blitted to a final DC.
If you could copy the code I posted and run it, you will see that its drawing noting although I'm following a step by step implementation.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900