如何让绘图时不闪烁?(100分)

  • 主题发起人 主题发起人 QSmile
  • 开始时间 开始时间
Q

QSmile

Unregistered / Unconfirmed
GUEST, unregistred user!
我在写一个绘图软件,相当于 Borland ImageEditor 。
绘图时是在一个放大的位图上写的。

我是这样处理的。
我建了两个 TImage, 一个是显示出来的。一个不显示从来,与实际大小一样。
显示从来那个叫 imgView 不显示的叫 imgBack 吧。
imgView 是放大的 imgBack.有网格。
画图时,我先在 imgBack 上画好,再用 StretchBlt 复制到 imgView 上。
再画上网格。 但这样闪烁太历害了。

有没有别的方法?
比如 ImageEditor 就没有闪。
 
在form的create里加一句代码:Doublebuffer := True;
 
楼上的兄弟说的对啊,楼主呢?

如楼上的兄弟所言,建立Doublebuffer这样的缓冲,可以消除闪烁!
 
加入“窗体名.Doublebuffered:=true;”以上代码可以消除闪烁!
 
不行,我刚才试了。
我说的是 imgView (绘图区) 闪烁,不是说窗口闪烁。
 
用一个PANEL试试,将图片放在PANEL中
不知道是不是哟,试试先!
 
实在不行的话,直接建立一个图片绘在它当中,最后在贴到imgView中。
可能速度会慢一点,但是看你的说明,数据量不大,速度应该不会有多大的变化。
 
to all;
好象这些方法都不行?
是不是要用计算机图形学,自己写出画线画圆的过程,分别在 imgView 与 imgBack 上画?
 
看看VCL上如何:
procedure TWinControl.WMPaint(var Message: TWMPaint);
var
DC, MemDC: HDC;
MemBitmap, OldBitmap: HBITMAP;
PS: TPaintStruct;
begin
// FDoubleBuffered=false则直接画到DC上。
if not FDoubleBuffered or (Message. DC <> 0) then
begin
if not (csCustomPaint in ControlState) and (ControlCount = 0) then
inherited
else
PaintHandler(Message);
end
// FDoubleBuffered=true则先画到缓冲区中,再复制到DC上
else
begin
// 建缓冲区
DC := GetDC(0);
MemBitmap := CreateCompatibleBitmap(DC, ClientRect.Right, ClientRect.Bottom);
ReleaseDC(0, DC);
MemDC := CreateCompatibleDC(0);
OldBitmap := SelectObject(MemDC, MemBitmap);
try
// 画到缓冲区上
DC := BeginPaint(Handle, PS);
Perform(WM_ERASEBKGND, MemDC, MemDC);
Message.DC := MemDC;
WMPaint(Message);
Message.DC := 0;
// 复制缓冲区到DC
BitBlt(DC, 0, 0, ClientRect.Right, ClientRect.Bottom, MemDC, 0, 0, SRCCOPY);
EndPaint(Handle, PS);
finally
SelectObject(MemDC, OldBitmap);
DeleteDC(MemDC);
DeleteObject(MemBitmap);
end;
end;
end;

因此,为防止闪烁,若控件有DoubleBuffered属性,则使DoubleBuffered=true即可;若无,则应自建缓冲区,进行后台绘制。
 
TImage 不是从 TWinControl 继承的。
 
双缓冲呀,这和用不用TImage无关。我都是直接在Canvas上画,或是用一个TPaintBox上面画,其实你要操作的是TCanvas对象。

建一个全局的TBitmap实例,大小尺寸和你的显示前景一样。画和擦都是在TBitmap中完成,最后再用前景Canvas.Draw(0,0, YourMemBitmap)或用StretchDraw均可。一点都不会闪的。

参阅我们的程序界面,多交流:

http://www.delphibbs.com/keylife/iblog_show.asp?xid=5798
 
会闪烁主要是程序在不停的更新画面,而更新速度太低所致。
采用控件的双缓冲可以缓解一部分问题,但是图片太大的时候就和画图的
方法有关系了。
我是采用和楼上一样的方法Canvas.Draw(x,y,BMP)这个方法是比较快的。
 
想用 TIMAGE????闪死你。。
自己用PAINTBOX。在上面贴图就是BitBlt或者Draw();BrushCopy()什么的。自己全部管理显示和刷新。否则。多余的刷新操作闪你不停。
 
是不是楼主设置DoubleBuffered的错误?这是我的猜测,楼主莫怪。
其实是设置Timage控件的paren的DoubleBuffered := true;
 
搂主呀,我以前也写过一个绘图的程序。用scanline填充时会有闪烁,在delphi6 下
后来在delphi 7下编译则没有了这种现象。加上上面各位说的双缓冲,和内存位图就没有问题了
 
to: kk2000
原来我犯了一个这样简单的错误!真不好意思。

好了,现在我的问题解决了。多谢各位的帮助了。
 
后退
顶部