各位帮忙看一看,图想翻转的问题。(50分)

M

mymy

Unregistered / Unconfirmed
GUEST, unregistred user!
我想让图形顺时针连续翻转90度。即点击鼠标一下为90度,两下为180度。
我已有用pixel的算法,但太慢。哪位大虾能用scanline作?
 
咋个用法?请指教
 
103. 图象旋转
在Form 中放一TImage(Image1)和一按钮,
将 Image1 的 AutoSize 设为 True.
连接按钮的以下点击事件:
点击按钮一下顺时针旋转 90 度。

90度:点一下。
180度:点两下。
270度:点击三下。

procedure TForm1.BitBtn1Click(Sender: TObject);
var
b:tImage;
i,j:Integer;
begin
with image1.Picture.Bitmap do
begin
b:=TImage.Create(nil);
b.Picture.Bitmap.assign(image1.Picture.Bitmap);
b.height:=Width;
b.Width:=Height;
for i:=0 to b.Height-1 do
for j := 0 to B.width -1 do
b.Canvas.Pixels[i,j]:=Canvas.Pixels[j,b.Height-1-i];
Assign(b.Picture.Bitmap);
end;
b.free;
end;
 
to jsxjd
谢谢的回答。我就是因为用pixel的算法图像翻转的速度太慢,才想用scanline.
 
翻转还是旋转?
翻转简单, 上下翻转只要将第一行与最后一行对调,第二行与倒数第二行对掉...,左右翻转 将每行的左半部分与右半部分对换即可。
旋转稍微复杂一点。我这里有个算法。而且是SmoothRotato哦。
等我改成scanline的(本来是直接操作DIB的)晚上贴给你。
 
to another_eyes
应该是旋转吧。多谢。也不是一定要用scanline,只要速度快。
 
不好意思。 这两天比较忙。(忙着写几个没什么用的控件:一个淡入淡出的滚动字幕,一个带活动水波倒影的Label, 还有一个逐字显示的提示文字)。
还没时间帮您改。 过几小时给您吧。其实就是把FastLib里的那个smoothrotate改成支持TBitmap和透明背景而已。
 
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1153142
 
大虾,我是想要一个顺时针的。
 
我也要一个顺时针90和任意角度的,谢谢大虾!
 
用scanline一样也要逐点运算,速度的快慢主要取决于图像的逐点绘制,故用DX和OPENGL才能根本解决问题。
 
我在网上看到一个逆时针的旋转,但不会把它改为顺时针的,也不知能否改。
请大虾帮帮忙。
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
begin
Inc(nMultiplier);
end;
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 component of the dst
(y * nMultiplier); // x component of the dst
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;
 
建议用汇编来做,又快又好。别扔鸡蛋。。。。。。。。。。
 
大虾们,帮我一下吧。
咋没人理我?
 
我也要一个顺时针90的
pengyi007@tellyes.com
谢谢!
 
to mymy: 上面不是很多人已经给你答案了吗? 如果你对旋转后图像质量要求不高(旋转成非90,180,270度时肯定存在一定的图像失真), 完全可以用他们的方法。至于顺时针的问题, 只要你传入的是负数的角度即可。
图像旋转算法很简单:
x':=(x*cos(A)-y*sin(A));
y' := (y*cos(A)+x*sin(A));
其中A := Angle*PI/180; (逆时针) 或 A := -Angle*PI/180; (顺时针)

如果你愿意等等, 我正在写一个高速平滑旋转透明位图的算法。
主要是想将Bresenhanm直线算法加入到图像旋转算法中(这样整个庞大的位图的计算就都是整数运算而不需要进行较慢的浮点运算了)。
 
谢谢,先给分吧。

 
多人接受答案了。
 
顶部