//参考如下代码 uses Math;procedure bmp_rotate(Src, Dst: TBitmap; Angle: Extended); var c1x, c1y, c2x, c2y: Integer; p1x, p1y, p2x, p2y: Integer; radius, n: Integer; alpha: Extended; c0, c1, c2, c3: TColor; begin c1x := src.width div 2; c1y := src.height div 2; c2x := dst.width div 2; c2y := dst.height div 2; // 步骤数值 number if c2x < c2y then n := c2y else n := c2x; dec(n, 1); //开始旋转 for p2x := 0 to n do begin for p2y := 0 to n do begin if p2x = 0 then alpha:= pi/2 else alpha := arctan2(p2y, p2x); radius := round(sqrt((p2x * p2x) + (p2y * p2y))); p1x := round(radius * cos(angle + alpha)); p1y := round(radius * sin(angle + alpha)); c0 := src.Canvas.Pixels[c1x + p1x, c1y + p1y]; c1 := src.Canvas.Pixels[c1x - p1x, c1y - p1y]; c2 := src.Canvas.Pixels[c1x + p1y, c1y - p1x]; c3 := src.Canvas.Pixels[c1x - p1y, c1y + p1x]; dst.Canvas.Pixels[c2x + p2x, c2y + p2y] := c0; dst.Canvas.Pixels[c2x - p2x, c2y - p2y] := c1; dst.Canvas.Pixels[c2x + p2y, c2y - p2x] := c2; dst.Canvas.Pixels[c2x - p2y, c2y + p2x] := c3; end; end; end;procedure TForm1.Button1Click(Sender: TObject); begin Image2.Picture.Bitmap := Image1.Picture.Bitmap; bmp_rotate(Image1.Picture.Bitmap, Image2.Picture.Bitmap, 0.25 * pi); end;procedure TForm1.Timer1Timer(Sender: TObject); const {$J+} vAngle: Real = 0; {$J-} begin Image2.Picture.Bitmap := Image1.Picture.Bitmap; vAngle := vAngle + (1 / 24) * pi; if vAngle > Pi * 2 then vAngle := 0; bmp_rotate(Image1.Picture.Bitmap, Image2.Picture.Bitmap, vAngle); end;
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 imagebegin // 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;
uses Math;procedure bmp_rotate(Src, Dst: TBitmap; Angle: Extended);
var
c1x, c1y, c2x, c2y: Integer;
p1x, p1y, p2x, p2y: Integer;
radius, n: Integer;
alpha: Extended;
c0, c1, c2, c3: TColor;
begin
c1x := src.width div 2;
c1y := src.height div 2;
c2x := dst.width div 2;
c2y := dst.height div 2;
// 步骤数值 number
if c2x < c2y then
n := c2y
else n := c2x;
dec(n, 1);
//开始旋转
for p2x := 0 to n do begin
for p2y := 0 to n do begin
if p2x = 0 then
alpha:= pi/2
else alpha := arctan2(p2y, p2x);
radius := round(sqrt((p2x * p2x) + (p2y * p2y)));
p1x := round(radius * cos(angle + alpha));
p1y := round(radius * sin(angle + alpha));
c0 := src.Canvas.Pixels[c1x + p1x, c1y + p1y];
c1 := src.Canvas.Pixels[c1x - p1x, c1y - p1y];
c2 := src.Canvas.Pixels[c1x + p1y, c1y - p1x];
c3 := src.Canvas.Pixels[c1x - p1y, c1y + p1x];
dst.Canvas.Pixels[c2x + p2x, c2y + p2y] := c0;
dst.Canvas.Pixels[c2x - p2x, c2y - p2y] := c1;
dst.Canvas.Pixels[c2x + p2y, c2y - p2x] := c2;
dst.Canvas.Pixels[c2x - p2y, c2y + p2x] := c3;
end;
end;
end;procedure TForm1.Button1Click(Sender: TObject);
begin
Image2.Picture.Bitmap := Image1.Picture.Bitmap;
bmp_rotate(Image1.Picture.Bitmap, Image2.Picture.Bitmap, 0.25 * pi);
end;procedure TForm1.Timer1Timer(Sender: TObject);
const
{$J+}
vAngle: Real = 0;
{$J-}
begin
Image2.Picture.Bitmap := Image1.Picture.Bitmap;
vAngle := vAngle + (1 / 24) * pi;
if vAngle > Pi * 2 then vAngle := 0;
bmp_rotate(Image1.Picture.Bitmap, Image2.Picture.Bitmap, vAngle);
end;
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 imagebegin
// 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;
用zswang(伴水清清)(专家门诊清洁工)的方法是可以做到不停的旋转了,但是在旋转的过程中,图片好像在不停的刷新,所以不停闪烁,有没有办法把这个给消除掉呢?
begin
DoubleBuffered := True;
end;
这是逆时针旋转,怎么样可以改为顺时什旋转呢?
{$J+}
vAngle: Real = Pi * 2;
{$J-}
begin
Image2.Picture.Bitmap := Image1.Picture.Bitmap;
vAngle := vAngle - (1 / 24) * pi;
if vAngle < 0 then vAngle := 2 * Pi;
bmp_rotate(Image1.Picture.Bitmap, Image2.Picture.Bitmap, vAngle);
end;