于双缓冲技术的GDI无闪烁绘图
- 格式:pdf
- 大小:754.46 KB
- 文档页数:4
C#环境下GDI+绘图效率研究作者:温铭毅来源:《中国科技博览》2015年第05期[摘要]本文在简单介绍GDI和GDI+的基础上,指出GDI+在绘制动画时效率不足的劣势,并对三种不同的GDI+动画绘图方式进行了详细的阐述;最后实现了一个GDI+界面绘图程序,比较和验证了三种不同方式的绘图性能。
实验表明,使用双缓冲和bitblt结合的方式,可以有效的解决直接绘制方式的闪烁问题,提高绘图效率。
[关键词]GDI+;动态绘图;双缓冲;bitblt中图分类号:P631.84 文献标识码:A 文章编号:1009-914X(2015)05-0134-011.引言GDI是微软公司的著名的二维图形引擎,GDI+则是微软公司为了提高显示效果而推出的一种新型图形引擎。
GDI是Graphics Device Interface的缩写,含义是图形设备接口,它的主要任务是负责系统与绘图程序之间的信息交换,处理所有Windows程序的图形输出。
GDI+是Windows XP中的一个子系统,它主要负责在显示屏幕和打印设备输出有关信息,它是一组通过C++类实现的应用程序编程接口。
顾名思义,GDI+是以前版本GDI的继承者,出于兼容性考虑,Windows XP仍然支持以前版本的GDI,但是在开发新应用程序的时候,开发人员为了满足图形输出需要应该使用GDI+,因为GDI+对以前的Windows版本中GDI进行了优化,并添加了许多新的功能。
作为图形设备接口的GDI+使得应用程序开发人员在输出屏幕和打印机信息的时候无需考虑具体显示设备的细节,他们只需调用GDI+库输出的类的一些方法即可完成图形操作,真正的绘图工作由这些方法交给特定的设备驱动程序来完成,GDI+使得图形硬件和应用程序相互隔离.从而使开发人员编写设备无关的应用程序变得非常容易。
Microsoft Windows GDI+服务分为以下3个主要部分:(1)二维矢量图形。
矢量图形由图元组成,而图元则由一系列坐标系统的点集组成。
一种基于自定义剪切区集合的MFC程序GDI绘图优化方法罗幸明,徐伟强浙江中控技术股份有限公司,浙江杭州,310053摘要:传统MFC程序GDI绘图仅考虑屏幕刷新闪烁的优化,而对于绘图内容本身的优化考虑有限。
常规应用下,GDI绘图本身确实不会成为程序的性能瓶颈,但在高分辨率、复杂画面的绘制显示时,这个问题就不得不考虑了。
通常我们会使用系统剪切区进行优化控制,但是实际应用发现当分辨率或者画面复杂度大于一定程度后,该优化的性能提升有限。
鉴于此,本文提出了一种简单可行的基于自定义剪切区集合判断的MFC程序GDI绘图优化方法,可以有效解决高分辨率、复杂画面的GDI绘图性能问题。
关键词:自定义剪切区、MFC、GDI、绘图One Optimizing Design Based On Custom Clipping Region Sets Of MFC Programs Drawing With GDILuo Xingming,Xu WeiqiangZhejiang SUPCON Co.,Ltd, Hangzhou, Zhejiang, 310053Abstract:When drawing with GDI of traditional MFC programs,the most considering things is the screen flashing problems but not drawing itself.Normally drawing performance will not be the choke point,but it really will be when screen resolution is high enough or graphics is complex enough.It is usual to resolve this problem by using system clipping region,but after some industial practice we found that the benefits from this optimizing is limited.Based on this situation,this paper presents a simple effective and practical optimizing design based on custom clipping region sets which can effectivly improve drawing performance of complex graphics in industrial field. Keyword:Custom Clipping Region Sets, MFC, GDI, Drawing基金项目“石化、轨道交通行业分布式综合监控系统(SCADA)研发及应用示范”资助1.GDI概述GDI(Graphics Device Interface)是Windows操作系统的传统图形子系统,负责与设备无关的图形绘制,Win32 API为应用程序提供了丰富的绘图函数和功能,而MFC又对他们进行了C++类的封装。
gdi双缓冲绘图.txt30生命的美丽,永远展现在她的进取之中;就像大树的美丽,是展现在它负势向上高耸入云的蓬勃生机中;像雄鹰的美丽,是展现在它搏风击雨如苍天之魂的翱翔中;像江河的美丽,是展现在它波涛汹涌一泻千里的奔流中。
以下是最简单的双缓冲代码,注释的地方很重要:CRect rect;static BOOL bColor=false;GetClientRect(&rect);CDC dcMem;dcMem.CreateCompatibleDC(pDC); //创建与视图的设备相兼容的内存设备,新的设备不具有与原设备相同的设备属性与背景色.CBitmap bmp;bmp.CreateCompatibleBitmap(pDC,rect.right,rect.bottom); //创建一个与视图兼容的位图,只有根据原设备来创建位图,才能从设备中获取像素点组成位图,因为双缓冲需要保留原设备中已有的图像,因此需要调用这个方法CBitmap* pOldBmp=dcMem.SelectObject(&bmp); //选择位图,只是修改了设备属性,并没有真正绘图.if(bColor){dcMem.SelectStockObject(WHITE_PEN);}else{dcMem.SelectStockObject(BLACK_PEN);}bColor=!bColor;for(int i=0;i<rect.Width();i++) {dcMem.MoveTo(i,0);dcMem.LineTo(i,rect.bottom);}pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dcMem,0,0,SRCCOPY); //将在内存中绘制好的图像重新显示到视图中,pDC与dcMem不必兼容.dcMem.SelectObject(pOldBmp);pOldBmp->DeleteObject();双缓冲技术绘图当数据量很大时,绘图可能需要几秒钟甚至更长的时间,而且有时还会出现闪烁现象,为了解决这些问题,可采用双缓冲技术来绘图。
使用双缓冲的图形可以减少或消除重绘显示图面时产生的闪烁。
使用双缓冲时,更新的图形首先被绘制到内存的缓冲区中,然后,此缓冲区的内容被迅速写入某些或所有显示的图面中。
显示图形的重写相对简短,这通常可以减少或消除有时在更新图形时出现的闪烁。
使用C# GDI+绘图,实现双缓冲绘图有几种方法,在这篇文章中,将介绍其中的一种——使用BufferedGraphics实现GDI+双缓冲绘图。
下面的代码示例演示如何使用BufferedGraphics对象绘制以下图形,这些图形使用几种类型的缓冲实现。
单击窗体将启动或停止一个计时器,该计时器将引起绘制更新。
绘制更新使您可以观察双缓冲的效果。
右击窗体将循环使用下列绘制模式:∙对于Form,直接绘制到Handle。
∙对使用OptimizedDoubleBuffer控件样式的OnPaint方法进行重写,以进行绘制∙对于不使用OptimizedDoubleBuffer控件样式的窗体方法,重写OnPaint方法以进行绘制。
在每种模式下都将绘制文本,以标识当前模式并描述按下每个鼠标按钮时发生的行为。
using System;using ponentModel;using System.Drawing;using System.Windows.Forms;namespace BufferingExample{public class BufferingExample : Form{private BufferedGraphicsContext context;private BufferedGraphics grafx;private byte bufferingMode;private string[] bufferingModeStrings ={ "Draw to Form without OptimizedDoubleBufferring control style","Draw to Form using OptimizedDoubleBuffering control style","Draw to HDC for form" };private System.Windows.Forms.Timer timer1;private byte count;public BufferingExample() : base(){// Configure the Form for this example.this.Text = "User double buffering";this.MouseDown += newMouseEventHandler(this.MouseDownHandler);this.Resize += new EventHandler(this.OnResize);this.SetStyle( ControlStyles.AllPaintingInWmPaint | erPaint, true );// Configure a timer to draw graphics updates.timer1 = new System.Windows.Forms.Timer();timer1.Interval = 200;timer1.Tick += new EventHandler(this.OnTimer);bufferingMode = 2;count = 0;// Retrieves the BufferedGraphicsContext for the// current application domain.context = BufferedGraphicsManager.Current;// Sets the maximum size for the primary graphics buffer// of the buffered graphics context for the application// domain. Any allocation requests for a buffer larger// than this will create a temporary buffered graphics// context to host the graphics buffer.context.MaximumBuffer = new Size(this.Width+1,this.Height+1);// Allocates a graphics buffer the size of this form// using the pixel format of the Graphics created by// the Form.CreateGraphics() method, which returns a// Graphics object that matches the pixel format of the form.grafx = context.Allocate(this.CreateGraphics(),new Rectangle( 0, 0, this.Width, this.Height ));// Draw the first frame to the buffer.DrawToBuffer(grafx.Graphics);}private void MouseDownHandler(object sender, MouseEventArgs e){if( e.Button == MouseButtons.Right ){// Cycle the buffering mode.if( ++bufferingMode > 2 )bufferingMode = 0;// If the previous buffering mode used// the OptimizedDoubleBuffering ControlStyle,// disable the control style.if( bufferingMode == 1 )this.SetStyle( ControlStyles.OptimizedDoubleBuffer, true );// If the current buffering mode uses// the OptimizedDoubleBuffering ControlStyle,// enabke the control style.if( bufferingMode == 2 )this.SetStyle( ControlStyles.OptimizedDoubleBuffer, false );// Cause the background to be cleared and redraw.count = 6;DrawToBuffer(grafx.Graphics);this.Refresh();}else{// Toggle whether the redraw timer is active.if( timer1.Enabled )timer1.Stop();elsetimer1.Start();}}private void OnTimer(object sender, EventArgs e){// Draw randomly positioned ellipses to the buffer.DrawToBuffer(grafx.Graphics);// If in bufferingMode 2, draw to the form's HDC.if( bufferingMode == 2 )// Render the graphics buffer to the form's HDC.grafx.Render(Graphics.FromHwnd(this.Handle));// If in bufferingMode 0 or 1, draw in the paint method.elsethis.Refresh();}private void OnResize(object sender, EventArgs e){// Re-create the graphics buffer for a new window size.context.MaximumBuffer = new Size(this.Width+1,this.Height+1);if( grafx != null ){grafx.Dispose();grafx = null;}grafx = context.Allocate(this.CreateGraphics(),new Rectangle( 0, 0, this.Width, this.Height ));// Cause the background to be cleared and redraw.count = 6;DrawToBuffer(grafx.Graphics);this.Refresh();}private void DrawToBuffer(Graphics g){// Clear the graphics buffer every five updates.if( ++count > 5 ){count = 0;grafx.Graphics.FillRectangle(Brushes.Black, 0, 0, this.Width, this.Height);}// Draw randomly positioned and colored ellipses.Random rnd = new Random();for( int i=0; i<20; i++ ){int px = rnd.Next(20,this.Width-40);int py = rnd.Next(20,this.Height-40);g.DrawEllipse(new Pen(Color.FromArgb(rnd.Next(0, 255),rnd.Next(0,255), rnd.Next(0,255)), 1),px, py, px+rnd.Next(0, this.Width-px-20), py+rnd.Next(0, this.Height-py-20));}// Draw information strings.g.DrawString("Buffering Mode:"+bufferingModeStrings[bufferingMode], new Font("Arial", 8), Brushes.White, 10, 10);g.DrawString("Right-click to cycle buffering mode", new Font("Arial", 8), Brushes.White, 10, 22);g.DrawString("Left-click to toggle timed display refresh", new Font("Arial", 8), Brushes.White, 10, 34);}protected override void OnPaint(PaintEventArgs e){grafx.Render(e.Graphics);}[STAThread]public static void Main(string[] args){Application.Run(new BufferingExample());}}}。
使用双缓存来解决GDI下的闪烁问题
韩丽娜;石昊苏
【期刊名称】《计算机工程与设计》
【年(卷),期】2006(27)17
【摘要】在图形图像处理过程中,当显示绘制的图像时,有时会出现闪烁的情况.本文从窗口、视口、坐标系统的基本概念和关系出发,主要讲解了如何使用双缓存来解决GDI下的闪烁问题.此方法已经应用于项目地质资料解释系统中对井曲线的修改和显示部分,实践证明,这种方法是可行的.
【总页数】3页(P3258-3260)
【作者】韩丽娜;石昊苏
【作者单位】西北大学,信息科学技术学院,陕西,西安,710069;咸阳师范学院,计算机科学系,陕西,咸阳,712100;西北政法学院,信息网络中心,陕西,西安,710063
【正文语种】中文
【中图分类】TP311.11
【相关文献】
1.在GDI+中使用双缓存 [J], 申晓
2.基于双缓存技术解决某模拟系统实时显示屏幕闪烁的方法 [J], 董燕;周燕明;崔卫兵
3.基于双缓存技术解决某模拟系统实时显示屏幕闪烁的方法 [J], 董燕;周燕明;崔卫兵
4.VC6.0下使用GDI+为应用程序添色彩 [J], 费之茵
5.基于双缓存技术解决某模拟系统实时显示屏幕闪烁的方法 [J], 董燕;周燕明;崔卫兵
因版权原因,仅展示原文概要,查看原文内容请购买。