A BitBlt-Like Function With Rotation Angle: ROTBlt

Environment: Visual C++


RotBlt is a function that works like BitBlt. It's different in that it has an additional param theta which is the angle in degrees by which the source DC is rotated when blitted onto the destination.

I wrote this in about 10 minutes, out of which I spent about 6 creating the Win32 app to test the code. So it is slow. (It took 1 second to rotate a 150x150x16bpp DC on a 333MHz Celeron.)

So if you wanted to rotate 1024x768x32 bits, umm, well....

Besides, I wrote this because I saw Hans Buhler's 90 degree rotate dc code which I assume has some issues with Win 95/98 and that seems to be for buttons and stuff. And then, why just 90 degrees??? Why not 3.635 degrees?

So, here's rotblt.

This is the code that generated this image.

  Rectangle (memDC,50,50,100,100);

  BitBlt(dc, 0,0,150,150,memDC,0,0,SRCAND);
  RotBlt(dc, 0,0,150,150,memDC,200,0, 45, SRCAND);

  TextOut(dc, 0,140,"BitBlt",strlen("BitBlt"));
  TextOut(dc, 200,140,"RotBlt 45 degs",strlen("RotBlt 45 degs"));

Function  : RotBlt
Parameters :
  HDC destDC, //destDC onto which to perform blt operation
  int srcx1,  //start x coordinate of src DC
  int srcy1,  //start y coordinate of src DC
  int srcx2,  //end x coordinate of src DC
              //remember this isn't width
  int srcy2,  //end y coordinate of src DC
              //remember this isn't height
  HDC srcDC , //srcDC
  int destx1, //left Xcoordinate of destDC where rotated DC will
              //be blt (top -left)
  int desty1 ,//top Ycoordinate of destDC where rotated DC will
              //be blt (top - left)
  int thetaInDegrees , // angle in degrees in which to rotate srcDC
  DWORD mode  //ROp code same as Bitblt

Return value : NULL

Body :

void RotBlt(HDC destDC, int srcx1, int srcy1, int srcx2, int srcy2,
  HDC srcDC , int destx1, int desty1 ,int thetaInDegrees ,DWORD mode)
  double theta = thetaInDegrees * (3.14159/180);
  //multiply degrees by PI/180 to convert to radians

  //determine width and height of source
  int width = srcx2 - srcx1;
  int height = srcy2 - srcy1;

  //determine centre/pivot point ofsource
  int centreX = int(float(srcx2 + srcx1)/2);
  int centreY = int(float(srcy2 + srcy1)/2);

  //since image is rotated we need to allocate a rectangle
  //which can hold the image in any orientation
  if(width>height)height = width;
    width = height;

  //allocate memory and blah blah
  HDC memDC = CreateCompatibleDC(destDC);
  HBITMAP memBmp = CreateCompatibleBitmap(destDC, width, height);

  HBITMAP obmp = (HBITMAP) SelectObject(memDC, memBmp);

  //pivot point of our mem DC
  int newCentre = int(float(width)/2);

  //hmmm here's the rotation code. X std maths :|
  for(int x = srcx1; x<=srcx2; x++)
    for(int y = srcy1; y<=srcy2; y++)
      COLORREF col = GetPixel(srcDC,x,y);

      int newX = int((x-centreX)*sin(theta)+(y-centreY)*cos(theta));
      int newY = int((x-centreX)*cos(theta)-(y-centreY)*sin(theta));

      SetPixel(memDC , newX + newCentre, newY + newCentre, col);

  //splash onto the destination
  BitBlt(destDC, destx1, desty1, width, height, memDC, 0,0,mode);

  //free mem and blah
  SelectObject(memDC, obmp);



  • It's been a elaborate week on account of prompt plant vent|fill alternate online

    Posted by Stoompota on 06/25/2013 04:33am

    elegance and luxury. A make-under of sorts, the minimal approach calls for subtle stepping out feeling refreshed in a chic and minimal outfit. There is nothing wrong accessories as well as the perfect handbag to add a touch of luxury. is that it's a "Back to Basics" transition, where we can shift towards classic pieces simple, focus on structure, clean lines, sophistication, and optimize the use of bold Follow our Blog | Let's talk on Twitter | Find us on Facebook There is a certain je ne [url=http://andysdm.com/]coach outlet[/url] sais quoi about leaving something to the imagination and Riki Rosetta New York Anastasia (Embossed Ostrich) White in our closets that we already own. Begin looking for items within your wardrobe that are quality staples; a structured blazer, a tapered trouser, a fitted button-down (cardigans will suffice!), a plain pump, and a pencil skirt. Remember to keep with being understated, fashionably speaking, in fact simplicity is the epitome of come to life, being that less in fact, is more. The great aspect of the Minimalist trend, For more Styling Tips, How-To's, and Outfit Posts: Riki Rosetta New York Anastasia (Embossed Ostrich) in Black silhouettes, demur details, [url=http://andysdm.com/]coach outlet for sale[/url] structured lines, and purely muted tones. The clich鑼? "I am Erica Lavelanet, one half of the wardrobe styling duo, behind the blog LPFashionPhilosophy. As a wardrobe stylist, I manage wardrobe for everything from editorial shoots to independent films and commercial print. I also work one on one with bands and artists, styling them for album covers, music videos, worldwide tours and [url=http://andysdm.com/]http://andysdm.com/[/url] appearances. Here, I'll be sharing a few of my formally [url=http://andysdm.com/]coach outlet[/url] unrevealed styling tips! This is fashion Q &A, where all of your handbag woes and fashion questions will be answered and transformed. The coup-de-gras? You don't need an entirely new wardrobe to revamp your closet - Maybe all you need is just a few new key pieces or accessories. And, Handbago, for a new clutch, satchel, messenger, or bucket bag, is the perfect place to start. " things as manageable and mild as possible. The modus operandi for Minimalism is blouse with barely there detailing, a heavy knit sweater in a timeless silhouette

  • More concessions with herveleger, more bring someone aback!

    Posted by mrslisaiiq on 04/26/2013 11:08am

    maidenskimpy shaverassent tosubornsizeablerep

  • More concessions with herveleger, more change off!

    Posted by Mrtopfliklb on 03/19/2013 03:17am

    herve leger swimwear herve leger outlet herve leger dresses sale herve leger gown herve leger stores herve leger outlet herve leger cheap iphone for sale cheap buy iphone 4s cheap iphones for sale cheap

  • Oh oh oh!

    Posted by Legacy on 01/25/2004 12:00am

    Originally posted by: Just guess!

    Hello little kids!

    Just check this code (in Pascal please!)

    Assume DC1 is the DC you want to rotate of an angle named o around its center. Assume DC2 is a DC with the same properties (pixelformat, dimensions...) as DC1. Assume w is the width of DC1 (and DC2), and that DC1 and DC2 are squares (then their heights are w too). DC2 is just a "transition DC" to make the intermediate computation (of course it could be created locally in the function).


    procedure Rotate(DC1,DC2:HDC;w:Integer;o:Single);
    for a:=0 to w-1 do begin
    for a:=0 to w-1 do begin

    I think this is at least 10 times faster than everything you wrote so far... except the great OpenGl, of course. You could do some optimization: in fact for o which is near 90� or 270�, it could be better to compute the first for-loop before the second one. But I think you are good enough to implement it yourself, I leave it as an exercise for the reader!

    Sorry, and excuse my poor English!

  • artifacts caused by a little mistake

    Posted by Legacy on 12/18/2003 12:00am

    Originally posted by: jes

    i think you intended to design the rotblt parameters to match bitblt, other than the added theta param. Your rotblt looks like:
    RotBlt(HDC destDC, int srcx1, int srcy1, int srcx2, int srcy2,HDC srcDC , int destx1, int desty1 ,int thetaInDegrees ,DWORD mode){...}

    while the bitblt usage is actually:
    BitBlt(destDC, destx, desty, width, height, srcDC, srcx, srcy, mode)

    your rotblt function still works, but will create holes (looks like scattered dot artifacts) because rotblt takes a pixel from the source, rotates it, and plots it into memDC. due to floating point to integer conversions, holes will be created. what you want to do is traverse the width/height of the destination DC, and use the trig to find the pixel in the source DC to copy into that location, which makes sure there are no holes in destDC.

    I was thinking that is what you intended to do but had some values in the parameter switched, but looking back, you did use wording such as "newX" and "newY", which implies to me that maybe it was ... in a way... unintentional and intentional at the same time? Perhaps renaming them to oldX and oldY would be less confusing.

    in any case, switching srcx1 and srcy1 with destx1 and desty1 in the for loop will correct the artifact issue, although the variable names should also be switched to avoid confusion. (i just left the names because im lazy)

    i actually dont mind the slow speed because i'm loading the rotations i need into ddraw surfaces before the gameplay begins. reading this article still saved me a lot of time :)

  • thanks for sharing

    Posted by Legacy on 12/16/2003 12:00am

    Originally posted by: jes

    i'm currently working on my first ddraw game which required rotation of bitmaps. I wanted to generate 360 rotated surfaces from 1 bmp, and wasn't quite sure what i could do with bitblt to achieve such rotations. i'm very much a beginner at programming... and found your code (and the comments) to be very helpful in what i wanted to do.

    thx :) -jes

  • Quit being so pretentious

    Posted by Legacy on 10/18/2003 12:00am

    Originally posted by: DrPhil

    Lay off the guy, programming may be a difficult task, but that is no reason to act snobby. Usually those people who say such things do so because of their low self efficacy. This appears to make them feel better about themselves.

  • Error

    Posted by Legacy on 08/22/2002 12:00am

    Originally posted by: sikander Rafiq

    Image is not rotated.

  • Remove GetPixel and SetPixel

    Posted by Legacy on 06/27/2002 12:00am

    Originally posted by: Rolf

    The inner loop can even be more simplified by eliminating the GetPixel and SetPixel calls. The resulting code will be at least 3 times faster and will benefit from the presence of a graphics accelerator card. The idea is simply to use the BitBlt function to set the pixel:

    int newX = int((x-centreX)*sin(theta) +(y-centreY)*cos(theta));
    int newY = int((x-centreX)*cos(theta)- (y-centreY)*sin(theta));
    BitBlt(memDC, newX+newCentre, newY+newCentre,1,1,srcDC,x,y,SRCCOPY);

  • Consider using Sin/Cos table

    Posted by Legacy on 06/26/2002 12:00am

    Originally posted by: Albert

    Consider using Sin/Cos tables instead of calling sin() and cos() in each iteration, that slow the process a lot. You can create your sin/cos tables everytime the project starts, so maybe the startup time is a little bit slower, but that will make your code faster. So, your program will have something like this:

    double sintable[360];

    void createsintable() {
    for (int i=0; i<360; i++) {
    sintable[i] = sin(i);

    I've not included the casting thingy, but you can figure it out by yourself. Call this function everytime the program starts.

  • Loading, Please Wait ...

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

Top White Papers and Webcasts

  • As all sorts of data becomes available for storage, analysis and retrieval - so called 'Big Data' - there are potentially huge benefits, but equally huge challenges...
  • The agile organization needs knowledge to act on, quickly and effectively. Though many organizations are clamouring for "Big Data", not nearly as many know what to do with it...
  • Cloud-based integration solutions can be confusing. Adding to the confusion are the multiple ways IT departments can deliver such integration...

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date