delphi 缓冲画图,内存画图解决画图闪烁问题

很多朋友在做绘图程序的时候,往往出现屏幕不停刷新产生闪烁的问题,这里就告诉大家一个解决办法,缓冲绘图。如果有人是用取反画图解决这个问题,那么在画直线的时候容易出现斑点,效果不是很好。如果是图片很大,那么缓冲画图是解决的好办法。

  在网上搜索一下内存绘图,或者缓冲绘图,会有很多技术文章,不过都是以vc或者java为主,很少有pascal的代码例子。不过原理都是一样的,大家可以参考他们的文章。我会在最后放上转载的vc缓冲画图的文章。:)感谢原作者。

  Delphi中函数调用比较方便。

  OldBmp, BufBmp是TbitMap

  //画图方法:

  procedure TChart.Draw(aCanvas: TCanvas);

  begin

  {把要画的操作放在这里}

  end;

  在你要画的地方用如下代码把内存中画好的内容放到你要显示的组件的canvas上,这里就是canvas:

  Draw (BufBmp.Canvas);//Draw方法就是上面那段代码

  bitblt(self.Canvas.Handle, 0, 0, ClientWidth, ClientHeight,

  self.BufBmp.Canvas.Handle, 0, 0, SRCCOPY);//拷贝函数

  如果要用多个缓冲,用BufBmp.Assign(OldBmp);做内存中图片内容复制,然后在bufbmp中做进一步操作,再贴到显示区。简单吧:)。

  怎样在内存缓冲中画图 

  介绍

用双缓冲进行绘图可解决在VC中绘图时的闪烁现象

  正文

用vc做程序,如何画图是一个大家都很关心,但是却感到很难以理解的问题,因为在 mfc的封装之下,没有现成的画图函数供你直接调用,像vb等等里面直接来个point之类的,常常让人感到无从下手。这两天帮人解决了一个用内存缓冲画 图的问题,顺便也就谈谈这些东西,也算是总结。

  我先来解释一下在mfc里面很关键的设备环境描述符,也就是所谓的DC(device context)。

  还是从历史来看吧,dos时代,我们如果要绘图,必须通过一系列系统函数来启动图形环境(用过 turbo pascal或者turbo c的人该还有印象吧),这之间对各种硬件的初始化参数都不相同,非常的烦人,常常还要查阅硬件手册,那时的程序智能针对最流行的硬件来编写,对不流行的就 没有办法了。windows操作系统为了屏蔽不同的硬件环境,让编程时候不考虑具体的硬件差别,采取了一系列办法,设备环境描述符就是这样产生的。简单的 说,设备描述符抽象了不同的硬件环境为标准环境,用户编写时使用的是这个虚拟的标准环境,而不是真实的硬件,与真实硬件打交道的工作一般交给了系统和驱动 程序完成(这同样解释了为什么我们需要经常更新驱动程序的问题)。使用在windows图形系统(gdi,而不包括direct x)上面,就体现在一系列的图形DC上面,我们如果要在gdi上面绘图,就必须先得到图形DC的句柄(handle),然后指定句柄的基础上进行图形操 作。

  再来回忆一下,我们怎么在sdk的环境下面绘图呢,我想这个大家都不太清楚吧,但是确实很基础。在windows的sdk环境下面,我们用传统的c编写程序,在需要的绘图地方(比如响应WM_PAINT消息的分支)这样做:

  hdc = GetDC( hwnd );

oldGdiObject = SelectObject( hdc,newGdiObject );

...绘图操作...

SelectObject( hdc,oldGdiObject );

DeleteObject( newGdiObject );

ReleaseDC( hdc);

  或者是这样

  BeginPaint( hwnd,&ps );//PAINTSTRUCT ps -- ps is a paint struct

...绘图操作...

EndPaint( hwnd )

  这就是大概的过程,我们看到了hdc(图形DC句柄)的应用,在绘图的部分,每一个绘图函数基本上 也要用到这个句柄,最后我们还必须释放它,否则将严重影响性能。每次我们都必须调用GetDC这个api函数得到(不能用全局变量保存结果重复使用,我在 后面解释)。这些是最最基本的windows图形操作的方式,相比dos时代简单了些,但是有些概念也难理解了些。vb里面的简单的point函数其实最 后也是被转化为这样的方式来执行,系统帮助做了很多事情。