SHARE
Facebook X Pinterest WhatsApp

Rotate a Bitmap at Any Angle Without GetPixel/SetPixel

Environment: Windows GDI / Win32 API Reason For This Article There is already an article on CodeGuru about rotating a bitmap at any angle. Unfortunately, it is very slow and produces some artifacts when rotating. The comments have focused on optimizing the floating point operations, but that is not the issue. The real issue is […]

Written By
thumbnail
CodeGuru Staff
CodeGuru Staff
Nov 19, 2002
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

Environment: Windows GDI / Win32 API

Reason For This Article

There is already an article on CodeGuru about rotating a bitmap at any angle. Unfortunately, it is very slow and produces some artifacts when rotating. The comments have focused on optimizing the floating point operations, but that is not the issue. The real issue is that GetPixel and SetPixel are abysmally slow. So, I wrote this program to demonstrate that it’s not the fault of the floating point calculations.

Using GetDIBits

This code is much faster because it uses GetDIBits to get the 32-bit representation of the bitmap to rotate. All operations are done in local memory rather than in slow API calls such as GetPixel or even BitBlt. I use the 32-bit representation mainly for its ease of use. When working with other color depths, you have to add some padding bytes at the end of each scan line, which is not necessary in 32 bits. Moreover, it allows easier access to the memory.

pBGR MyGetDibBits(HDC hdcSrc, HBITMAP hBmpSrc, int nx, int ny)
{
  BITMAPINFO bi;
  BOOL bRes;
  pBGR buf;
  bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
  bi.bmiHeader.biWidth = nx;
  bi.bmiHeader.biHeight = – ny;
  bi.bmiHeader.biPlanes = 1;
  bi.bmiHeader.biBitCount = 32;
  bi.bmiHeader.biCompression = BI_RGB;
  bi.bmiHeader.biSizeImage = nx * 4 * ny;
  bi.bmiHeader.biClrUsed = 0;
  bi.bmiHeader.biClrImportant = 0;
  buf = (pBGR) malloc(nx * 4 * ny);
  bRes = GetDIBits(hdcSrc, hBmpSrc, 0, ny, buf, &bi,
                   DIB_RGB_COLORS);
  if (!bRes) {
    free(buf);
    buf = 0;
  }
  return buf;
}

RotateMemoryDC

This function does all the work. Apart from getting the source coordinate from a target coordinate, it is very straightforward. The formulas I use are these:

orgX = (cA * (((float) stepX + OfX) + CtX * (cA – 1)) + sA * (((float) stepY + OfY) + CtY * (sA – 1))) / cA*cA + sA*sA;

orgY = CtY + (CtX – ((float) stepX + OfX)) * sA + cA *(((float) stepY + OfY) – CtY + (CtY – CtX) * sA);

cA is just cos(angle) and sA is sin(angle). CtX and CtY are the center of the source image and OfX and OfY are the offsets of the source image inside the target image. This is necessary because the target image has to be bigger than the source.

I actually make a point of using floating point operations in the inner loop to show that the performance does not depend on these. In the old days of DOS, when PCs were slow at floating point operations and graphics manipulation was fast because it consisted only of accessing a special part of the system memory, the bottleneck was indeed the floating point operations. With GDI, this is unfortunately not true anymore. Most of the time is taken up by getting the bitmaps and setting them.

Changing the calculations to fixed point math will only result in a marginal improvement in the overall speed.

General Notes

The program is based on the sample “Hello World” application generated by Visual C++ 6. I just added the new drawing code and a Timer so that the bitmap rotates continuously.

Downloads


Download demo project – 25 Kb


Download source – 10 Kb

Recommended for you...

Drawing 3D OpenGL Graphics on Google Maps
Mandelbrot Using C++ AMP
CodeGuru Staff
Jan 27, 2012
Simple C++ MP3 Player Class
CodeGuru Staff
Aug 22, 2011
Library for Raw Video Processing
CodeGuru Staff
Jun 14, 2011
CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2025 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.