游子日月长

笑渐不闻声渐悄,多情却被无情恼!

导航

封面图片任意旋转 任意旋转图像 处理速度快 自动中心位置寻找

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. 

 

posted on 2017-02-08 17:12  游子日月长  阅读(200)  评论(0编辑  收藏  举报