Rotating a Bitmap by 90 Degrees

Last reviewed: November 2, 1995
Article ID: Q77127
The information in this article applies to:
  • Microsoft Windows Software Development Kit (SDK) for Windows versions 3.1 and 3.0
  • Microsoft Win32 Application Programming Interface (API) included with:

        - Microsoft Windows 95 version 4.0
    

SUMMARY

There are no Windows functions that directly rotate bitmaps. All techniques for rotating bitmaps in Windows involve copying the rows from a source bitmap into the columns of a destination bitmap. The following contains code for rotating a bitmap using GetPixel() and SetPixel(), and contains an outline of code for rotating device independent bitmaps (DIB).

MORE INFORMATION

A device dependent bitmap (DDB) can be rotated using the GetPixel() and SetPixel() functions. To rotate the bitmap, use the following code:

HBITMAP Rotate90(HDC hDC, HBITMAP hSourceBitmap) {

  HBITMAP hOldSourceBitmap, hOldDestBitmap, hDestBitmap;
  HDC hMemSrc, hMemDest;
  int height, width;
  int i, j;
  BITMAP iSrcBitmap;

  // Step 1: Create a memory DC for the source and destination bitmaps
  //         compatible with the device used.

  hMemSrc = CreateCompatibleDC(hDC);
  hMemDest= CreateCompatibleDC(hDC);


  // Step 2: Get the height and width of the source bitmap.

  GetObject(hSourceBitmap, sizeof(BITMAP), (LPSTR)&SrcBitmap);
  width = SrcBitmap.bmWidth;
  height = SrcBitmap.bmHeight;


  // Step 3: Select the source bitmap into the source DC. Create a
  //         destination bitmap, and select it into the destination DC.

  hOldSourceBitmap = SelectObject(hMemSrc, hSourceBitmap);
  hDestBitmap = CreateBitmap(height, width, SrcBitmap.bmPlanes,
                    SrcBitmap.bmBitsPixel, NULL);

  if (!hDestBitmap)
    return(hDestBitmap);

  hOldDestBitmap = SelectObject(hMemDest, hDestBitmap);


  // Step 4: Copy the pixels from the source to the destination.

  for (i = 0; i < width; ++i)
      for (j = 0; j < height; ++j)
          SetPixel(hMemDest, j, width - 1 - i,
                                            GetPixel(hMemSrc, i, j));


  // Step 5: Destroy the DCs.

  SelectObject(hMemSrc, hOldSourceBitmap);
  SelectObject(hMemDest, hOldDestBitmap);
  DeleteDC(hMemDest);
  DeleteDC(hMemSrc);


  // Step 6: Return the rotated bitmap.

  return(hDestBitmap);
}

If the bitmap is larger, using GetPixel() and SetPixel() may be too slow. If this is the case, there are two options:

  1. If the contents of the bitmap do not change, create two versions of the bitmap, the normal version and one that is rotated by 90 degrees. Load the appropriate bitmap as required.

-or-

  1. Find some way to manipulate the bits of the bitmap that is faster than using SetPixel() and GetPixel(). The best way to do this is to convert the bitmap to a device independent bitmap. The following four steps detail how to create the DIB and to perform the rotation:

    a. Use GetDIBits() to convert the bitmap to a device independent

          format. It is necessary to create a BITMAPINFO structure
          appropriate for the bitmap. This will write the bitmap as a
          series of scanlines. Each scanline is padded so that it is DWORD
          aligned.
    

    b. Allocate memory for the destination bitmap. This bitmap requires

          as many scanlines as the width of the source bitmap. Each
          scanline is as many pixels wide as the height of the source
          bitmap. Also, the scanlines must be DWORD aligned.
    

    c. For each scanline in the source bitmap, copy the pixels to the

          appropriate column in the destination bitmap. NOTE: The format
          for each scanline depends upon the number of bits per pixel. See
          the BITMAPINFO documentation for a description of the possible
          formats.
    

    d. Use SetDIBits() to copy the device independent bits into a

          device dependent bitmap. Another BITMAPINFO structure,
          appropriate for the destination device is required for this
          step.
    

The four steps of this method require much more work than is required if GetPixel() and SetPixel() are used; however, this method may be faster because it directly manipulates the bits in the bitmap.


Additional reference words: 3.00 3.10 4.00 95
KBCategory: kbgraphic
KBSubcategory: GdiBmp


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: November 2, 1995
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.