位图如何快速旋转,求好方法(22分)

  • 主题发起人 主题发起人 117924
  • 开始时间 开始时间
1

117924

Unregistered / Unconfirmed
GUEST, unregistred user!
我用以下语句将1500*1122位图转了90度,
BmpD.Canvas.Pixels[(-I + Image1.Height), J] := BmpS.Canvas.Pixels[J, I];
可是足足让我等了六分钟,求一好的方法,谢
 
这样的处理,你千万别用 Pixels,M$ 自己都承认它慢,
用 ScanLine 吧
 
旋转90度的快速方法 : 在Image1上加载一幅位图

type
EInvalidPixelFormat = class(Exception);

const
BitsPerByte = 8;

function GetPixelSize(aBitmap: TBitmap): integer;
var
nBitCount, nMultiplier: integer;
begin
case aBitmap.PixelFormat of
pfDevice:
begin
nBitCount := GetDeviceCaps(aBitmap.Canvas.Handle, BITSPIXEL);
nMultiplier := nBitCount div BitsPerByte;
if (nBitCount mod BitsPerByte)>0 then
Inc(nMultiplier);
end;
pf1bit: nMultiplier := 1;
pf4bit: nMultiplier := 1;
pf8bit: nMultiplier := 1;
pf15bit: nMultiplier := 2;
pf16bit: nMultiplier := 2;
pf24bit: nMultiplier := 3;
pf32bit: nMultiplier := 4;
else raise EInvalidPixelFormat.Create('Bitmap pixelformat is unknown.');
end;
Result := nMultiplier;
end;

procedure ImageRotate90(aBitmap: TBitmap);
var
nIdx, nOfs,
x, y, i,nMultiplier: integer;
nMemWidth, nMemHeight, nMemSize,nScanLineSize: LongInt;
aScnLnBuffer: PChar;
aScanLine: PByteArray;
begin
nMultiplier := GetPixelSize(ABitmap);
nMemWidth := aBitmap.Height;
nMemHeight := aBitmap.Width;
nMemSize := nMemWidth * nMemHeight * nMultiplier;
GetMem(aScnLnBuffer, nMemSize);
try
nScanLineSize := aBitmap.Width * nMultiplier;
GetMem(aScanLine, nScanLineSize);
try
for y := 0 to aBitmap.Height-1 do
begin
Move(aBitmap.ScanLine[y]^, aScanLine^, nScanLineSize);
for x := 0 to aBitmap.Width-1 do
begin
nIdx := ((aBitmap.Width-1) - x) * nMultiplier;
nOfs := (x * nMemWidth * nMultiplier) +(y * nMultiplier);
for i := 0 to nMultiplier-1 do
Byte(aScnLnBuffer[nOfs + i]) := aScanLine[nIdx+i];
end;
end;
aBitmap.Height := nMemHeight;
aBitmap.Width := nMemWidth;
for y := 0 to nMemHeight-1 do
begin
nOfs := y * nMemWidth * nMultiplier;
Move((@(aScnLnBuffer[nOfs]))^, aBitmap.ScanLine[y]^, nMemWidth * nMultiplier);
end;
finally
FreeMem(aScanLine, nScanLineSize);
end;
finally
FreeMem(aScnLnBuffer, nMemSize);
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
ImageRotate90(Image1.Picture.Bitmap);
end;
 
卷起千堆雪tyn,的方法好像很要内存
如果运行下代码要30秒
bitmap:=TBitmap.Create;
ImageRotate90(Bitmap);
 
什么?
你用30秒?有没有搞错啊?
你在Image事先加载一幅位图,试试看,真是。。。。。。怪。。。
 
大家不要急,不知道你用的是什么牛机? 286 or 386 之类的?

用一段类似楼上写的旋转过程,在我的机器上(CPU :k6-266)大概要0.1-0.2秒左右(640X480)
如果是在单位的机器(CPU :P3, 933)翻转一幅1024X768的图,大概要0.08-0.09秒
 
[?]我的机器是C800,在Image事先加载一幅位图转动没问题----很快,但用TBitmap.Create创
建一位图转动就慢了,找个大点的位图试试就知道。
 
C++Builder的,自已改成Delphi的吧!
void S_PicXZ(Graphics::TBitmap *Source,Graphics::TBitmap *NewPic)
{
NewPic->Height=Source->Width;
int www=Source->Width;
NewPic->Width=Source->Height;
int g=Source->Height;
int k=Source->Width;
Byte *ptr;
Byte *newscanline;
NewPic->PixelFormat = Source->PixelFormat;
for (int y =0;y<k-1;y++)
{
newscanline =(Byte*)NewPic->ScanLine[y];
for (int x =0;x <g-1;x++){
ptr = (Byte*)Source->ScanLine[x];
int i,j;
i=x*3;
j=y*3;
newscanline = ptr[www*3-j];
newscanline[i-1] = ptr[www*3-j-1];
newscanline[i-2] = ptr[www*3-j-2];
}
}
}
 
卷起千堆雪tyn的例子好像没有反应啊
 
接受答案了.
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
481
import
I
I
回复
0
查看
625
import
I
D
回复
0
查看
2K
DelphiTeacher的专栏
D
后退
顶部