请问如何实现图象旋转90度速度快(10分)

  • 主题发起人 主题发起人 amartapple
  • 开始时间 开始时间
A

amartapple

Unregistered / Unconfirmed
GUEST, unregistred user!
我用pixles写的,奇慢
 
用控件,现在这种控件应该不少!
不用控件的话好像用scanline转的快一些.
Another_eYes在这方面是专家,找他没错
他的一段代码
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);
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;


不过说实话我用了后不知道怎么回事,我得没动静。后来不搞那块也就没管他了!


 
yysun (1999-2-8 0:58:00)
刚刚发现<a href=/delphi/attachments/fastbmp.zip>TFastBMP</a> 能:
- 自由缩放图像
- 任意旋转图像
- 锐化 / 钝化图像
- 特殊效果处理 e.g. 马赛克,加杂音点 ...

简直是个小小 Photoshop. With Delphi source ! 速度也不错!

再次推荐.

 
卷起千堆雪tyn (2001-11-9 12:23:00)
实现图象的旋转,你用的是最基本的象素操作法;
其实这种方法看起来简单,但是只要图象稍微大一点,它的操作速度就会很慢。
建议你用扫描线的方法,也就是ScanLine来实现旋转,它是整行整行的操作,速度绝对快。
关于扫描线,你可以看看我在http://www.delphibbs.com/delphibbs/dispq.asp?lid=486743
里面的使用,稍微修改就OK.

 
哦,不好意思,又翻了一下

那个Another_eYes的程序这样才行:
必须是24位真彩图才行.
可以用Bitmap.PixelFormat := pf24Bit;强行将Bitmap转成24位真彩再调用
 
谢谢大家,这个问题可以结束了
不过我想知道<a href=/delphi/attachments/fastbmp.zip>TFastBMP</a> 在哪里
 
不行,我加了Bitmap.PixelFormat := pf24Bit;也不行,这是代码
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);
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;

procedure TForm1.Button1Click(Sender: TObject);
var
Point:TPoint;
begin
Point.X:=0;
Point.Y:=0;
Image1.Picture.Bitmap.PixelFormat := pf24Bit ;
RotateBmp(Image1.Picture.Bitmap,Point,90);
end;

end.
 
看看这个例子,只能在Win2k和NT下运行
http://www.undu.com/LIBS/plgblt.zip
 
做的是不错,可惜只能在Win2k和NT下运行
不适合我用,还是谢谢
 
还有么,我就是想把一个图片旋转90度,速度要快
 
唉,其实我也一直在找fastbmp,可是就是没发现,你去
这里看看吧,反正里面有不少号称能旋转图片的控件,可惜我
没测试,自己试试吧!http://www.tommstudio.com/newclub30/
那个不行的话找another_eyes吧,
 
不清楚您的需要,写一个逆时针旋转90度的:

procedure RotateBMP(BMP:TBitmap);
var
TempBmp:TBitmap;
i,j,W,temp:Integer;
begin
temp:=Integer(BMP.PixelFormat);
BMP.PixelFormat:=pf32bit;
TempBmp:=TBitmap.Create;
try
TempBmp.Assign(BMP);
W:=BMP.Width;
BMP.Width:=BMP.Height;
BMP.Height:=W;
Dec(W);
for i:=0 to BMP.Height-1 do
for j:=0 to BMP.Width-1 do
PInteger(Integer(BMP.ScanLine[W-i])+j*4)^:=
PInteger(Integer(TempBmp.ScanLine[j])+i*4)^;
BMP.PixelFormat:=TPixelFormat(temp);
finally
TempBmp.Free;
end;
end;
 
感谢大家

楼上的不错,速度能不能再快点,大概有1秒的延时
 
把你详细情况(调入图形,显示图形代码)说一说,我可以给你再快点。
 
非常感谢,这是全部代码

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Image1: TImage;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure RotateBMP(BMP:TBitmap);
var
TempBmp:TBitmap;
i,j,W,temp:Integer;
begin
temp:=Integer(BMP.PixelFormat);
BMP.PixelFormat:=pf32bit;
TempBmp:=TBitmap.Create;
try
TempBmp.Assign(BMP);
W:=BMP.Width;
BMP.Width:=BMP.Height;
BMP.Height:=W;
Dec(W);
for i:=0 to BMP.Height-1 do
for j:=0 to BMP.Width-1 do
PInteger(Integer(BMP.ScanLine[W-i])+j*4)^:=
PInteger(Integer(TempBmp.ScanLine[j])+i*4)^;
BMP.PixelFormat:=TPixelFormat(temp);
finally
TempBmp.Free;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
RotateBMP(Image1.Picture.Bitmap);
end;

end.
 
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, jpeg, ExtCtrls, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Image1: TImage;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
TempBmp:TBitmap;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure RotateBMP(BMP,TempBmp:TBitmap);
var
i,j,W:Integer;
ScOrg,ScDest:Array of PIntegerArray;
begin
TempBmp.Assign(BMP);
W:=BMP.Width;
BMP.Width:=BMP.Height;
BMP.Height:=W;
Dec(W);

SetLength(ScDest,BMP.Height);
SetLength(ScOrg,TempBmp.Height);
for i:=0 to BMP.Height-1 do ScDest:=BMP.ScanLine;
for i:=0 to TempBmp.Height-1 do ScOrg:=TempBmp.ScanLine;

for i:=0 to BMP.Height-1 do
for j:=0 to BMP.Width-1 do
ScDest[W-i][j]:=ScOrg[j];
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
RotateBMP(Image1.Picture.Bitmap,TempBmp);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Image1.Picture.Bitmap.PixelFormat:=pf32bit;
TempBmp:=TBitmap.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
TempBmp.Free;
end;

end.

快了不少,上面要关联FormCreate,FormDestroy两个事件,就不用我多说了吧!
 
这里没有环境,明天我试试
 
我也来一贴,特点是简单,旋转 90 度一步到位。要更快,就要使用内存交换了,
业余用用的话,就这样也可以了:
procedure TForm1.Button1Click(Sender: TObject);
var
i, j:integer;
SrcBitmap,DestBitmap:TBitmap;
t:DWord;
begin
t:=GetTickCount;
try
SrcBitmap:=Image1.Picture.Bitmap;

DestBitmap:=TBitmap.Create;
DestBitmap.Width:=SrcBitmap.Height ;
DestBitmap.Height:= SrcBitmap.Width;

for i := 0 to SrcBitmap.Width-1 do
begin
for j := 0 to SrcBitmap.Height-1 do
begin
SetPixel(DestBitmap.Canvas.Handle, j,SrcBitmap.Width-i,
GetPixel(SrcBitmap.Canvas.Handle, i, j));
end;
end;

Image1.Picture.Bitmap:= DestBitmap;
finally
Caption:=Format('这次旋转 90 度耗时: %d 毫秒',[GetTickCount-t]);
FreeAndNil(DestBitmap);
end;
end;
 
如用扫描线,则应注意BMP的颜色深度,如24位,则每个点是3个字节,分别用1个字节表示
R、G、B,如是12位,则分别用4Bit表示。看看帮助。
 
hhxxj:
fastbmp控件找到了吗?给我一个地址,我也要找啊,找不到
 
后退
顶部