封面图片任意旋转 任意旋转图像 处理速度快 自动中心位置寻找
unit UnitMain; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Math, StdCtrls, jpeg, ExtCtrls, ComCtrls; type TForm1 = class(TForm) Button1: TButton; Image1: TImage; Button2: TButton; Image2: TImage; TrackBar1: TTrackBar; Button3: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private procedure bmp_rotate(src,dst:tbitmap;angle:extended); public { Public declarations } end; procedure rotate(sur:pchar;bmp:Tbitmap;cx,cy:integer;angle:integer); procedure RotateBmp(bmp: TBitmap; Center: TPoint; angle: Integer); var Form1: TForm1; implementation uses UnitBitmapRotate; {$R *.dfm} procedure TForm1.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 //将角度转换为PI值 angle := (angle / 180) * pi; // 计算中心点,你可以修改它 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; application.processmessages end; end; procedure TForm1.Button1Click(Sender: TObject); var bmp:TBitMap; a: pbytearray; Center: TPoint; begin bmp:=TBitMap.create; bmp.Assign(Image1.Picture.Graphic); //AntiAlias(Bmp); Center.X := Bmp.Width div 2; Center.Y := Bmp.Height div 2; RotateBmp(Bmp, Center, 10); Image1.Picture.Assign(Bmp); Bmp.free; end; procedure rotate(sur:pchar;bmp:Tbitmap;cx,cy:integer;angle:integer); var x1,y1,x3,y3 :integer; //x1,y1 为平移坐标 x3,y3为旋转的新坐标 x,y,h,w,widthbytes,dst,v:integer; hcos,hsin:double; tmp:Pcolor; hu:double; begin hu:=angle*3.1415/180; hcos:=cos(hu); hsin:=sin(hu); h:=bmp.Height; w:=bmp.Width ; widthbytes:=integer(bmp.scanline[0])-integer(bmp.scanline[1]); dst:=integer(bmp.ScanLine[h-1]); fillchar(pchar(dst)^,widthbytes*h,0); //使图像全黑 for y:=0 to h-1 do begin y1:=y -(h-cy); //平移下的y for x:=0 to W-1 do begin x1:=x-cx; //平移下的x x3:=round(x1*hcos-y1*hsin); y3:=round(x1*hsin+y1*hcos); //平移下的新坐标 x3:=x3+cx; y3:=y3+(h-cy); //转换回原坐标 if (x3>=0) and (x3<w-1) and (y3>=0) and (y3<h-1) then pcolor(dst+x*3+y*widthbytes)^:= pcolor(integer(sur)+x3*3+y3*widthbytes)^; end; end; end; //angle为旋转的角度,cx、cy为旋转中心, cx=width div 2,cy=height div 2即以图像的中心为旋转中心。此程序处理速度快,可处理大图片。 procedure TForm1.Button2Click(Sender: TObject); var Bmp: TBitmap; begin Button2.Enabled := False; Bmp := TBitmap.Create(); Bmp.Width := Image1.Width ; Bmp.Height := Image1.Height; Bmp.Assign(Image1.Picture.Bitmap); Bmp.SaveToFile('1.bmp'); bmp_rotate(Image1.Picture.Bitmap, Bmp, 10 - TrackBar1.Position); Image1.Picture.Bitmap.Assign(Bmp); Bmp.Free(); Button2.Enabled := True;; end; procedure RotateBmp(bmp: TBitmap; Center: TPoint; angle: Integer); var tmpbmp: TBitmap; i, j, x, y, px, py: Integer; cAngle, sAngle: extended; p1, p2: Pchar; begin while angle < 0 do angle := angle + 360; angle := angle mod 360; sAngle := sin(- angle * pi / 180); cAngle := cos(- angle * pi / 180); tmpbmp := tbitmap.create; tmpbmp.assign(bmp); for i := 0 to tmpbmp.height - 1 do begin p1 := pchar(tmpbmp.scanline[i]); py := 2 * (i - center.y) - 1; for j := 0 to tmpbmp.width - 1 do begin px := 2 * (j - center.x) - 1; x := (round(px * cAngle - py * sAngle) - 1) div 2 + center.x; y := (round(px * sAngle + py * cAngle) - 1) div 2 + center.y; if (x>=0) and (x<tmpbmp.width) and (y>=0) and (y<=tmpbmp.height) then begin p2 := pchar(bmp.scanline[y]) + x * 3; move(p1^, p2^, 3); end; inc(p1, 3); end; end; end; end.