Mega Code Archive

 
Categories / Delphi / Examples
 

Bitmap rotation

Rotate a Bitmap Image in 90-Degree Increments 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;