求最快的图像旋转90度算法,我这儿给出个最普通的//旋转90
procedure TForm1.Button3Click(Sender: TObject);
var
w,h:integer;
b1,b2:TBitmap;
src,drc:TRect;
i,j:integer;
begin
b1:=TBitmap.Create;
b2:=TBitmap.Create;
b1.Assign(Image1.Picture.Graphic);
w:=b1.Width;
h:=b1.Height;
b2.Width:=h;
b2.Height:=w;
for i:=0 to h-1 do begin
for j:=0 to w-1 do
b2.Canvas.Pixels[i,w-j]:=b1.Canvas.Pixels[j,i];
end;
Image2.Picture.Bitmap.Assign(b2);
b1.Free;
b2.Free;
end;
procedure TForm1.Button3Click(Sender: TObject);
var
w,h:integer;
b1,b2:TBitmap;
src,drc:TRect;
i,j:integer;
begin
b1:=TBitmap.Create;
b2:=TBitmap.Create;
b1.Assign(Image1.Picture.Graphic);
w:=b1.Width;
h:=b1.Height;
b2.Width:=h;
b2.Height:=w;
for i:=0 to h-1 do begin
for j:=0 to w-1 do
b2.Canvas.Pixels[i,w-j]:=b1.Canvas.Pixels[j,i];
end;
Image2.Picture.Bitmap.Assign(b2);
b1.Free;
b2.Free;
end;
im:Tbitmap;
begin
im:=Tbitmap.Create;
im.Assign(jpbmp(Tjpegimage(image1.Picture.Graphic)));
image1.Picture.Bitmap.Height:=im.Width;
image1.Picture.Bitmap.Width:=im.Height;
image1.Picture.CleanupInstance;
for i:=0 to im.Height do
for j:=0 to im.Width do
image1.Canvas.Pixels[i,(-j+im.Width)]:=im.Canvas.Pixels[j,i];
im.Free;
end;
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, ExtDlgs;
type
THelpRGB = packed record
rgb: TRGBTriple;
dummy: byte;
end;
type
pRGBArray = ^TRGBArray;
TRGBArray = array[0..32767] of TRGBTriple;type
TForm1 = class(TForm)
Button1: TButton;
Image1: TImage;
Button2: TButton;
OpenPictureDialog1: TOpenPictureDialog;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure Rotate(Bitmap: TBitmap);
var
aStream: TMemorystream;
//内存流
header: TBITMAPINFO;
dc: hDC;
P: ^THelpRGB;
x, y, b, h: Integer;
RowOut: pRGBArray;
begin
//创建内存流
aStream := TMemoryStream.Create;
//设置大小,必须是4的倍数
aStream.SetSize(Bitmap.Height * Bitmap.Width * 4);
with header.bmiHeader do //操作位图文件
begin
biSize := SizeOf(TBITMAPINFOHEADER); //大小
biWidth := Bitmap.Width; //位图宽
biHeight := Bitmap.Height; //位图高
biPlanes := 1;
biBitCount := 32;
//无压缩
biCompression := 0;
biSizeimage := aStream.Size;
biXPelsPerMeter := 1; //水平分辨率
biYPelsPerMeter := 1; //竖直分辨率
biClrUsed := 0;
biClrImportant := 0;
end;
dc := GetDC(0);
P := aStream.Memory;
GetDIBits(dc, Bitmap.Handle, 0, Bitmap.Height, P, header, dib_RGB_Colors);
ReleaseDC(0, dc);
b := bitmap.Height; //源图高
h := bitmap.Width; //源图宽
//指定要创建的位图的大小尺寸
bitmap.Width := b;
bitmap.height := h;
for y := 0 to (h - 1) do
begin
rowOut := Bitmap.ScanLine[y]; //获取新的位图信息
P := aStream.Memory; //设置文件指针
inc(p, y); //指针移位
for x := 0 to (b - 1) do
begin
rowout[x] := p^.rgb; //进行数据转移
inc(p, h);
end;
end;
aStream.Free; //释放资源
end;procedure TForm1.Button1Click(Sender: TObject);
begin
Rotate(image1.Picture.Bitmap);
end;procedure TForm1.Button2Click(Sender: TObject);
begin
if OpenPictureDialog1.Execute then
image1.Picture.Bitmap.LoadFromFile(OpenPictureDialog1.FileName);
end;end.
速度差异其实不在与算法,而在于你访问图像数据的方式,
用Pixels由于delphi封装了图像的读取与保存,因此你每次访问一个Pixels,都会重复的对读写进行读取和保存,速度会是最慢的,更快的方法当然是采用ScanLine循环获取整张图像数据到一个二维数组,再对二维数组进行运算,最后将二维数组写到图像中显示,但是这是后长宽如果不相等,你可能需要采取缩放运算,或者越界处理,其实还有一种更快一些,就是调用BitBlt复制整张图片数据,比ScanLine快一些,后续动作基本一样