求助!关于绘图程序刷新!!三个问题各100分献上!!!

natrium11 2001-04-14 10:46:00
我用 Delphi 5 编了一个绘图程序,用如下方法完成鼠标作图:

procedure TForm1.ImageMouseDown(Sender:TObject,...);//保存以前图象
begin
SaveImage.Canvas.Draw(0,0,Image.Picture.Bitmap);
OriginX=X;
OriginY=Y;

//...
end;

procedure TForm1.ImageMouseMove(Sender:TObject,...);//在Image上作随鼠标位而定的直线
begin
Image.Canvas.Draw(0,0,SaveImage.Picture.Bitmap);
Image.Canvas.MoveTo(OriginX,OriginY);
Image.Canvas.LineTo(X,Y);
end;

procedure TForm1.ImageMouseUp(Sender:TObject,...);//在Image上完成绘图
begin
Image.Canvas.Draw(0,0,SaveImage.Picture.Bitmap);
Image.Canvas.MoveTo(OriginX,OriginY);
Image.Canvas.LineTo(X,Y);
end;

这样每次移动鼠标都会导致一次 Canvas.Draw 和一次重画,结果发现屏幕闪烁另人无法容忍,问各位有何高招?
我看见许多书上都说用 XOR 解决,但那样会损坏背景,不知实践中是如何应用的?

另外还有就是用什么办法可以方便的保存以前画的部分,以供选中和编辑?

另外,将一块形状不规则的区域送入剪贴板是如何实现的(Lasso工具)?
...全文
266 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
natrium11 2001-05-30
  • 打赏
  • 举报
回复
呜呼,我还以为我已结了呢!!怎么回事??
Kingron 2001-05-30
  • 打赏
  • 举报
回复
赫赫,你要作一个画图?直接用OLE就可以乐,调用Windows的画笔,一摸一样的,菜单都是一样的.:)
natrium11 2001-04-20
  • 打赏
  • 举报
回复
唉,看来是给分得时候了,可惜我最多只能给55分哦。
(csdn真搞不懂,我明明有二千多分,却只能给55)
natrium11 2001-04-20
  • 打赏
  • 举报
回复
Paint也没人会编啊,呜呼!
natrium11 2001-04-19
  • 打赏
  • 举报
回复
原来Windows Paint也是猛程序,唉!
natrium11 2001-04-19
  • 打赏
  • 举报
回复
但是Windows画图?天哪。。。
完全的前景色画图,没有一点点闪烁!!
natrium11 2001-04-18
  • 打赏
  • 举报
回复
To WuHeHai(河海):
和白色异或不就是求反吗?那得到的也就是背景色的反色,那如果背景色很复杂的话,画出的线可就好看了!有没有好一些的方法??
WuHeHai 2001-04-18
  • 打赏
  • 举报
回复
保存图像,不知这个例子是否适合你?
procedure TForm1.Button1Click(Sender: TObject);
var
DC: HDC;
Canvas: TCanvas;
MyBitmap: TBitmap;
begin
Canvas := TCanvas.Create;
MyBitmap := TBitmap.Create;
DC := GetDC(0);

try
Canvas.Handle := DC;
with Screen do
begin
{ detect the actual height and with of the screen }
MyBitmap.Width := Width;
MyBitmap.Height := Height;

{ copy the screen content to the bitmap }
MyBitmap.Canvas.CopyRect(Rect(0, 0, Width, Height), Canvas,
Rect(0, 0, Width, Height));
{ stream the bitmap to disk }
MyBitmap.SaveToFile('c:\windows\desktop\screen.bmp');
end;

finally
{ free memory }
ReleaseDC(0, DC);
MyBitmap.Free;
Canvas.Free
end;
oldhawk 2001-04-18
  • 打赏
  • 举报
回复
可用WindowAPI中得InvalidateRect函数,将其中得参数设为你要刷新得区域,就不会全屏重画,而只重画指定区域。
WuHeHai 2001-04-18
  • 打赏
  • 举报
回复
即使背景色很复杂,效果也挺好的,你若觉不够好,可以用点线来模拟画线,
然后再mouseup事件中才真正地画线,
我再给你一个例子吧:

var
Form1: TForm1;
OriginX, OriginY: integer;
OldX, OldY : integer;

implementation

{$R *.DFM}

Procedure TForm1.DrawLine(X, Y: integer);
begin
Image1.Canvas.Pen.Color := clBlack;
Image1.Canvas.Pen.Style := psDot ;
Image1.Canvas.Pen.Mode := pmXor;
Image1.Canvas.MoveTo(OriginX, OriginY);
Image1.Canvas.LineTo(X, Y);
end;

procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
OriginX := X; OriginY := Y;
OldX := X; OldY := Y;
end;

procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if (ssLeft in Shift) or (ssRight in Shift) then
begin
DrawLine(OldX, OldY);
OldX := X; OldY := Y;
DrawLine(X, Y);
end;
end;

procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Image1.Canvas.Pen.Style := psSolid;
Image1.Canvas.Pen.Color := clGreen;
Image1.Canvas.Pen.Mode := pmCopy;
Image1.Canvas.MoveTo(OriginX, OriginY);
Image1.Canvas.LineTo(X, Y);
end;
Kingron 2001-04-18
  • 打赏
  • 举报
回复
WuHeHai的方法已经很完美了,你另外的问题要另外开贴子。

没有约定的透明色,一般是取左下角(还是其他的地方?)的像素的颜色作为透明色。
natrium11 2001-04-18
  • 打赏
  • 举报
回复
高手,你在何方?这应该不是商业机密吧?!
natrium11 2001-04-18
  • 打赏
  • 举报
回复
Windows中有没有约定的透明色?还是取某个角落里的颜色为背景?
WuHeHai 2001-04-17
  • 打赏
  • 举报
回复
这个我也不太清楚。我刚来CSDN...
菜鸟一只
natrium11 2001-04-17
  • 打赏
  • 举报
回复
我决不会食言的,不过问一个白痴问题(不要打我),csdn给分一定要问题完成之后吗?为什么我想中途给分给少一点又不行,全给后马上算成问题结束了?
WuHeHai 2001-04-17
  • 打赏
  • 举报
回复
可以通过设置异或操作避免屏幕闪烁
我刚写了代码,基本能合你需求。

var
OriginX, OriginY: integer;
OldX, OldY : integer;

Procedure TForm1.DrawLine(X, Y: integer);
begin
Image1.Canvas.Pen.Color := clWhite;
Image1.Canvas.Pen.Mode := pmXor;
Image1.Canvas.MoveTo(OriginX, OriginY);
Image1.Canvas.LineTo(X, Y);
end;

procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
OriginX := OldX; OriginY := OldY;
end;

procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
DrawLine(OldX, OldY);
OldX := X; OldY := Y;
DrawLine(X, Y);
end;

呵呵!你会给那么多分数吗?我岂不是账大了!!!
natrium11 2001-04-17
  • 打赏
  • 举报
回复
你不是说用BitBlt来保存以前所画物体吧?那要多少个Canvas(Bitmap)啊?
有没有更好的方法?
natrium11 2001-04-17
  • 打赏
  • 举报
回复
1.MouseMove时不能不画呀!鼠标拖动时得给用户一个可视的回应啊。连Windows Paint都是这样子的。
2。Erase 原来的直线不好实现吧,我又不知道原来的背景是什么。
3。我也有试过只重画所涉及的最小矩形(Image.Canvas.CopyRect),效果仍不好.
Kingron 2001-04-17
  • 打赏
  • 举报
回复
用bitblt可以把以前的画面保存下来。
Kingron 2001-04-17
  • 打赏
  • 举报
回复
MouseMove中不要画!在MouseUp的时候才画一次就可以了。
其实你在MouseMove中也可以画,但是不要Draw整个Image,只要erase原来的直线,然后Draw一个直线就可以了,否则Draw整个画面,当然闪烁了。
加载更多回复(4)

5,392

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧