Rotate Bitmap

Top  Previous  Next

 

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;