delphi3000.com - the free delphi knowledge platform
delphi3000.com - the free delphi knowledge platform
494 Users Online NOW
Have a look at your member-status

connecting people's knowledge


  - Recent ArticlesRSS feed for Recent Articles on delphi3000.com
  - List of All Articles
  - Top Viewed Articles
  - Articles (+Attachem.)
  - Articles Of Interest
  - Categories
  - Top Uploader
  - Search
  - Index

  - My Home
  - Submit an Article
  - My Articles
  - My Personal Data
  - My Bookmarks
  - Activities
  - Login/Logout

  - Sign Up
  - Why Sign Up
  - Newsletter

  - Press
  - Advertise

  - Contact
  - Feedback





Community
Borland
ClubeDelphi
Dr. Bob
UK-BUG
Delphi Meetings
Planeta Delphi



Loremo - the 1.5 liter car coming in 2009




Startblatt.de






Share this article with friendsShare this article with friends
Rate this articleRate this article - to keep the quality of delphi3000.com !
Comment this article or read through previous comments (2)


Bitmap rotationGo to Serhiy Perevoznyk's websiteFormat this article printer-friendly!Bookmark function is only available for registered users!
Product:
Delphi all versions
Category:
Graphic
Skill Level:
Scoring:
Last Update:
03/18/2003
Search Keys:
delphi delphi3000 article borland vcl code-snippet Windows,API,Bitmap
Times Scored:
3
Visits:
2565
Uploader: Serhiy Perevoznyk
Company: http://users.chello.be/ws36637
Reference: N/A
 
Question/Problem/Abstract:
Rotate a Bitmap Image in 90-Degree Increments
Answer:



Bitmap rotation is a graphic effect that Delphi does not natively offer. This article shows how to rotate a given image in 90-degree increments. It allows you to rotate any image 0, 90, 180 or 270 degrees. With a little work, the code can be modified to rotate to any angle, but that is beyond the scope of this article.

procedure RotateBitmap(var hBitmapDC : Longint; var lWidth : Longint;
         var lHeight : Longint; lRadians : real);
var
         I : Longint;               // loop counter
         J : Longint;               // loop counter
         hNewBitmapDC : Longint;    // DC of the new bitmap
         hNewBitmap : Longint;      // handle to the new bitmap
         lSine : extended;          // sine used in rotation
         lCosine : extended;        // cosine used in rotation
         X1 : Longint;              // used in calculating new
                                    //   bitmap dimensions
         X2 : Longint;              // used in calculating new
                                    //     bitmap dimensions
         X3 : Longint;              // used in calculating new
                                    //     bitmap dimensions
         Y1 : Longint;              // used in calculating new
                                    // bitmap dimensions
         Y2 : Longint;              // used in calculating new
                                    // bitmap dimensions
         Y3 : Longint;              // used in calculating new
                                    // bitmap dimensions
         lMinX : Longint;           // used in calculating new
                                    // bitmap dimensions
         lMaxX : Longint;           // used in calculating new
                                    // bitmap dimensions
         lMinY : Longint;           // used in calculating new
                                    // bitmap dimensions
         lMaxY : Longint;           // used in calculating new
                                    // bitmap dimensions
         lNewWidth : Longint;       // width of new bitmap
         lNewHeight : Longint;      // height of new bitmap
         lSourceX : Longint;        // x pixel coord we are blitting
                                    // from the source  image
         lSourceY : Longint;        // y pixel coord we are blitting
                                    // from the source image

begin
         // create a compatible DC from the one just brought
         // into this function
         hNewBitmapDC := CreateCompatibleDC(hBitmapDC);

         // compute the sine/cosinse of the radians used to
         // rotate this image
         lSine := Sin(lRadians);
         lCosine := Cos(lRadians);

         // compute the size of the new bitmap being created
         X1 := Round(-lHeight * lSine);
         Y1 := Round(lHeight * lCosine);
         X2 := Round(lWidth * lCosine - lHeight * lSine);
         Y2 := Round(lHeight * lCosine + lWidth * lSine);
         X3 := Round(lWidth * lCosine);
         Y3 := Round(lWidth * lSine);

         // figure out the max/min size of the new bitmap
         lMinX := Min(0, Min(X1, Min(X2, X3)));
         lMinY := Min(0, Min(Y1, Min(Y2, Y3)));
         lMaxX := Max(X1, Max(X2, X3));
         lMaxY := Max(Y1, Max(Y2, Y3));

         // set the new bitmap width/height
         lNewWidth := lMaxX - lMinX;
         lNewHeight := lMaxY - lMinY;

         // create a new bitmap based upon the new width/height of the
         // rotated bitmap
         hNewBitmap := CreateCompatibleBitmap(hBitmapDC, lNewWidth, lNewHeight);

         //attach the new bitmap to the new device context created
         //above before constructing the rotated bitmap
         SelectObject(hNewBitmapDC, hNewBitmap);

         // loop through and translate each pixel to its new location.
         // this is using a standard rotation algorithm
         For I := 0 To lNewHeight do begin
            For J := 0 To lNewWidth do begin
               lSourceX := Round((J + lMinX) * lCosine + (I + lMinY) * lSine);
               lSourceY := Round((I + lMinY) * lCosine - (J + lMinX) * lSine);
               If (lSourceX >= 0) And (lSourceX <= lWidth) And
               (lSourceY >= 0) And (lSourceY <= lHeight) Then
                   BitBlt(hNewBitmapDC, J, I, 1, 1, hBitmapDC,
                              lSourceX, lSourceY, SRCCOPY);
            end;
         end;

         // reset the new bitmap width and height
         lWidth := lNewWidth;
         lHeight := lNewHeight;

         // return the DC to the new bitmap
         hBitmapDC := hNewBitmapDC;

         // destroy the bitmap created
         DeleteObject(hNewBitmap);

      End;

The following is an example of how the RotateBitmap function might be called:

procedure TForm1.RotateTest(Sender: TObject);
var
lRadians : real;
DC  : longint;
H, W : integer;
Degrees : integer;
begin
  Degrees := 45;
  lRadians := PI * Degrees / 180;
  DC := Image1.Picture.Bitmap.Canvas.Handle;
  H := Image1.Picture.Bitmap.Height;
  W := Image1.Picture.Bitmap.Width;
  RotateBitmap(DC, W, H, lRadians);
  Image1.Width := W;
  Image1.Height := H;
  Image1.Picture.Bitmap.Width := W;
  Image1.Picture.Bitmap.Height := H;
  BitBlt(Image1.Picture.Bitmap.Canvas.Handle, 0, 0, W, H, DC, 0, 0, SRCCopy);
  Image1.Refresh;
end;






Please rate this article!
Skill level:
BeginnerExpert

Useful:
No!Very!

Overall rating:
PoorExcellent



Comments to this article
Write a new comment
The angle of rotation in the test
    Hein Mank (Nov 5 2004 10:31PM)

The example procedure 'RotateTest' submits an angle of 45 degree. That is too bad, because rotating an image over 45 degrees will deteriorate the image and the images also becomes bigger as a black surrounding area is gradually added.
When I use a 90 degree angle, it works really perfect! Exactly what I was looking for.
Respond

RE: The angle of rotation in the test
first last (May 4 2006 10:33AM)

You need something a lot faster and simpler of you want to rotate 90, 180 or 270 degrees! Just resize the bitmap and reposition it's pixels. (something like... img [x,y] := img [y,x]). I will not paste the whole code as there already are articles here about how to do that !
Respond














 
Sign up to consume product discounts for Bronze memberships !

read more


  Visit our Sponsor

 

  Community Ad of
E. DSpirito
 
   














 







     
  Copyright © 2000 - 2007 delphi3000.com - All rights reserved. Terms of use. || Privacy
delphi3000.com is a service by bluestep.com IT-Services GmbH (Vienna)