Anti-Aliased Image Rotation (Aarot)

written by Mark Gordon (msg555)

Image rotation isn't as straightforward as it may appear, especially when faced with the fact that, although small, a pixel is not a point. In fact, it's a 1 x 1 square, which leads to the question of how best to rotate it. Some algorithms will ingore this idea altogether and treat a pixel like a point. Others will do an artificial zooming on the image to make the smallest unit of color even smaller so the aliasing won't be as evident. However, it is possible to rotate a pixel as a square, and Aarot does it. By treating a pixel like a square, you get the best rotation possible.

To learn how to perform anti-aliased image rotation, please see the companion article.

Aarot works by rotating each of the 1 x 1 squares from the source bitmap and overlapping them on the destination bitmap. Because pixels can only hold one discrete color, it is necessary to find how much representation each source pixel has in each destination pixel. Aarot does this by finding the area of each source pixel over each destination pixel and adding representation proportional to that area.

See the following image. On the left, you see the unrotated image; the next step shows the rotated image overlapped on the destination bitmap. In the final step, the amount of representation each source pixel should receive in each destination pixel is calculated and added to the destination pixels

Unfortunatly, this algorithm does not complete in real time so it is not useful for games or things of the like. I wrote the algorithm for C++ and VB (C++ is faster) and provided a DLL for implementing the C++ algorithm's speed with VB. (There are sample projects as well.)

I included a comparison between Aarot and Photoshop (CS2) so you can see the difference between the two. Here is an example of Aarot's work:

Logo rotated 38.47 degrees

Implementation

C++ Prototype

HBITMAP aarot::rotate(HBITMAP src, double rotation,
                      aar_callback callbackfunc, int bgcolor,
                      bool autoblend)

VB Function

Public Function Aarot(Src As Long, Rotation As Double, _
                      CallBackPtr As Long, BgColor As Long, _
                      AutoBlend As Boolean) As Long

VB DLL Declare

Private Declare Function aarotate Lib "aarot.dll" _
   Alias "_Z17AntiAliasedRotateidiii" _
   (ByVal hSrcBmp As Long, ByVal Rotation As Double, _
    ByVal Callbackfunc As Long, ByVal BgColor As Long, _
    ByVal AutoBlend As Long) As Long
  • Src: A handle to the bitmap to be rotated.
  • Rotation: The degrees that the image should be rotated counter-clockwise.
  • callbackfunc (CallBackPtr): A pointer to the callback function. This function will be notified what percentage of the rotation has completed as well as given the opportunity to stop the rotation. This parameter may be NULL (or 0 in VB). See Using the Callback Function below for information about the Callback structure.
  • BgColor: The color of the background where the rotated bitmap does not overlap the destination bitmap.
  • AutoBlend: Should the edges of the rotated image be blended with the background color defined by BgColor? If false, the rgbReserved byte of each pixel will be set to the approriate alpha values so that the rotated image can be blended onto another image later without a harsh edge.

Using the Callback Function

In C++, the callback function should look like this:

bool AarotCallbackFunc(double percentdone)
{
   ...
}

where percentdone is the amount of the image that has processed. 0 is 0%, 1 is 100%.

If you are using the DLL in VB, your callback function should look like this:

Public Function AarotCallbackFunc(ByVal Percentage As Double) As Long
...
End Function

On the other hand, if you are using the VB module, your callback should look like this (due to a need to have 16 bytes' worth of parameters to use CallWindowProc):

Public Function AarotCallbackFunc(ByVal Percentage As Double, _
                                  ByVal Numerator As Long, _
                                  ByVal Denominator As Long) As Long
...
End Function

where Percentage means the same thing, and Numerator and Denominator make up the rationale used to calculate Percentage.

No matter what you're using, if your callback function returns true (anything but 0), the main algorithm will immediatly exit (after clearing the memory) and return a null bitmap.



Downloads

Comments

  • Use this function in VBA (Access)

    Posted by ymkx on 01/23/2007 03:18am

    This function is what I have been looking for, for over 3 months now. Thanks, it is great! The problem is that Access does not have a PictureBox object where I can assign the result of the rotation. How can I send the result to an Image Object? yaacov@rampal.com

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Wednesday, September 24, 2014 8:00 AM - 9:00 AM PDT According to a recent Forrester Research report, many companies are choosing low-code platforms over traditional programming platforms, due to the speed with which low-code apps can be assembled and tested. With customer-facing applications on the rise, traditional programming platforms simply can't keep up with the "short schedules and rapid change cycles" required to develop these applications. Check out this upcoming webinar and join Clay Richardson from …

  • Live Event Date: September 17, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT Another day, another end-of-support deadline. You've heard enough about the hazards of not migrating to Windows Server 2008 or 2012. What you may not know is that there's plenty in it for you and your business, like increased automation and performance, time-saving technical features, and a lower total cost of ownership. Check out this upcoming eSeminar and join Rich Holmes, Pomeroy's practice director of virtualization, as he discusses the …

Most Popular Programming Stories

More for Developers

RSS Feeds