请帮忙看看下面的让一个图像产生水平镜像的代码为什么不行?(47分)

  • 主题发起人 主题发起人 ynduanlian
  • 开始时间 开始时间
Y

ynduanlian

Unregistered / Unconfirmed
GUEST, unregistred user!
我写了这个函数来产生一个BMP的水平镜像图:
function MirrorBmp(const SBmp: TBitmap): TBitmap;
var
RBmp: TBitmap;
I: Integer;
begin
Result:=nil;
RBmp:=TBitmap.Create;
RBmp.Width:=Sbmp.Width;
RBmp.Height:=Sbmp.Height;
if (SBmp <> nil) then
begin
for I:=0 to SBmp.Width do
SBmp.Canvas.CopyRect(Rect(SBmp.Width-I,0,SBmp.Width-I,SBmp.Height),RBmp.Canvas,Rect(I,0,I,Sbmp.Height));
Result:=RBmp;
end;
end;


函数的调用:
procedure TfrmMain.Button1Click(Sender: TObject);
var
SBmp: TBitmap;
DBmp: TBitmap;
begin
SBmp:=TBitmap.Create;
DBmp:=TBitmap.Create;
SBmp.LoadFromFile('C:/1.bmp');
DBmp:=MirrorBmp(SBmp);
if (DBmp <> nil) then
DBmp.SaveToFile('C:/2.bmp');
end;

结果发现C:/2.bmp总是一张空白图,问题出在哪里啊?
 
经调式:
//Result:=RBmp; 得到的结果是正确的,但是赋值语句出错
不调用函数,直接保存 SBmp.SaveToFile('C:/2.bmp'); 得正解

关注
 
为什么?
 
哇塞,这个代码还要“经调试”哇?

这个代码根本不用经调试,看一看就知道这十来行代码有半数严重错误。

最根本的,这是在谁操作谁啊?SBmp?DBmp?RBmp?画天书啊?
 
用SCANLINE好些
 
RBmp.Height:=Sbmp.Height;
if (SBmp <> nil) then

你不觉得这粮行有点颠倒吗?
如果SBmp=nil第一行就可能会有异常
根本执行不到下面
 
因为Rect(SBmp.Width-I,0,SBmp.Width-I,SBmp.Height)和Rect(I,0,I-1,Sbmp.Height)
这两个矩形的宽度总是0,所以不包含任何像素,而且拷贝和被拷贝的对象也弄反了
建议改成下面的
function MirrorBmp(const SBmp: TBitmap): TBitmap;
var
I: Integer;
begin
Result := nil;
if SBmp = nil then
exit
else
Result := TBitmap.Create;

Result.Width := Sbmp.Width;
Result.Height := Sbmp.Height;

for I := 1 to SBmp.Width do
Result.Canvas.CopyRect(Rect(SBmp.Width - I + 1, 0, SBmp.Width - I, SBmp.Height),
SBmp.Canvas, Rect(I, 0, I - 1, Sbmp.Height));
end;

如果是大图片的话用ScanLine会快一些
 
多人接受答案了。
 
后退
顶部