`
cloudtech
  • 浏览: 4605621 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

提高二维矢量绘图效率之一般做法

 
阅读更多

作者:朱金灿

来源:http://blog.csdn.net/clever101

这个问题很普遍。最近在研究这个问题,在网上搜了一些资料,再结合自己的经验,谈谈自己的一些想法。

一.双缓存能提高绘图效率吗?

网上有篇文章:绘图效率完整解决方案——三种手段提高GDI/GDI+绘图效率,其中提到一种方法是:1. 缓存——Bitmap或者DoubleBuffer。缓存就是先把绘制的图形绘制到一张内存位图上,然后在一次性的贴位图,他可以提高绘图速度,也能避免闪烁。DoubleBuffer=true是C#窗体的属性,设置了此属性估计系统本身会起用无效区的内存位图缓存,而不需要程序员Bitmap处理。

这里对双缓存的通常做法不作介绍,网上的相关资料很多。说实话,我对使用双缓存能提升绘图效率表示怀疑,理由很简单,同是DC,同是绘制1000条线段,有什么理由内存DC就比窗口DC快(当然这个我没有作具体的测试,这个有空可以测试下)。我还稍微怀疑使用双缓存绘图比直接使用窗口DC绘图还慢一些,理由有二:一是使用双缓存需要增加创建内存DC和内存位图的操作;二是使用双缓存还需要增加一个把内存DC拷贝到窗口DC的操作。那么双缓存的主要作用是什么?其实就是解决绘图过程的闪烁问题,改善绘图效果。

二.Windows环境下二维绘图引擎的选取

和绘图效率的一个重要相关因素是绘图引擎。Windows环境下二维绘图引擎有多种选择:GDI、GDI+、DirectDraw、QT、Agg、Cairo、skia、Direct2D、Direct3D、OpenGL等。下面我逐一作一个简单的分析:

GDI:微软原生的二维绘图引擎。

优点:微软的全力支持,作为操作系统核心层效率方面不用担心,支持多种开发框架(含语言):Win SDK、MFC、Delphi等。

缺点:基于过程,缺乏面向对象,使用起来不太方便,不支持反锯齿,不支持复杂的绘图效果(这个相对于GDI+而言)。

GDI+:微软后来推出的二维绘图引擎。

优点:微软的全力支持,支持多种开发框架(含语言):Win SDK、MFC、Delphi等,可以实现复杂的绘图效果,如反锯齿、路径画刷等;面向对象的架构,使用起来比较方便。

缺点:绘图效率较GDI稍低,绘图交互性不如GDI(缺少GDI的支持位运算的绘图模式),开启反锯齿后效率不如QT。

有关GDI和GDI+的详细比较,请看我以前写的一篇文章:GDI和GDI+的应用场合思考

DirectDraw:从GDI、GDI+到Direct 2D的一个过渡产品,微软已明确表示不推荐使用,在MicrosoftDirectX SDK (June 2010)已看不到它的身影,在此不作介绍。

QT:开源跨平台(基于LGPL协议),面向对象的方式组织,使用起来较为方便。

Agg:C++编写的开源绘图引擎(基于GPL协议)

Cairo:C编写的开源绘图引擎(基于LGPL协议),大名鼎鼎的FireFox就是用这个绘图引擎的。

有关Agg和Cairo请参考这篇文章:Agg vs. Cairo 二维绘图引擎之比较和选择。该文作者比较推崇Cairo,但据我公司的一个同事介绍:Cairo的绘图效率很慢。具体我没有做过测试。

Skia:Google的Android的绘图引擎。

Direct2D:微软在WindowsVista及之后的Windows版本推出的意在取代GDI、GDI+的二维绘图引擎,支持硬件加速。

Direct3D:微软开发的3D绘图引擎。

OpenGL:SGI开发的3D绘图引擎。

上面简单对Windows下的二维绘图引擎作了一个简单介绍。我的推荐是:开发商业产品一般情况下在Windows XP及以下Windows版本使用GDI和GDI+,在Windows Vista及其之后的Windows版本(如Win 7)使用Direct2D。理由是:跨平台的绘图引擎如Agg、Cairo之类的,出于跨平台封装的需要,必然会牺牲一部分性能,就是说它本来就是封装GDI的,怎么可能超出GDI的绘图效率呢?还有就是诸如Agg还有开源协议的限制,这样就排除了开源二维绘图引擎。我也不推荐使用Direct3D、OpenGL等三维绘图引擎进行二维绘图,理由是三维绘图可以利用硬件加速,绘图速度应该比GDI、GDI+快,但三维绘图引擎一般是基于三维的数据结构进行组织的,对二维绘图并不合适,比如以前我们曾利用OpenGL进行二维绘图,发现OpenGL在二维一些操作并不合适,如二维中的点、线捕捉、自定义图例的添加、打印的支持等等。所以我倾向于使用GDI、GDI+。GDI的一大缺点是由于不是面向对象组织的,使用起来较为繁琐。这个我觉得可以参考GDI+的面向对象封装的方式对GDI进行封装。Direct 2D是微软在后XP时代开发的开发二维绘图引擎。微软出于兼容性的考虑还会继续对GDI、GDI+进行支持,但毫无疑问微软的策略是要Direct 2D取代GDI和GDI+的,因此在WindowsVista及其之后的Windows上进行二维绘图开发我建议是直接使用Direct2D。Direct 2D支持硬件加速,在绘图效率应有一定程度的提升。

三.提高GDI绘图效率的常用做法

提高GDI绘图效率的一般原则可以简单概括为:尽量减少无效绘图区域,尽量减少不必要的绘图操作。

尽量减少绘图区域的通常做法是:

  1. 设置裁剪区。裁剪区的作用就是:只有在这个区内的绘图过程才会真正有效,在区外的是无效的,即使在区外执行了绘图函数也是不会显示的。因为多数情况下窗口重绘的产生大多是因为窗口部分被遮挡或者窗口有滚动发生,改变的区域并不是整个图形而只有一小部分,这一部分需要改变的就是pDC中的裁剪区了。因为显示(往内存或者显存都叫显示)比绘图过程的计算要费时得多,有了裁剪区后显示的就只是应该显示的部分,大大提高了显示效率。但是这个裁剪区是MFC设置的,它已经为我们提高了显示效率,在进行复杂图形的绘制时如何进一步提高效率呢?那就只有去掉在裁剪区外的绘图过程了。可以先用pDC->GetClipBox()得到裁剪区,然后在绘图时判断你的图形是否在这个区内,如果在就画,不在就不画。

  1. 减少无效区域。在GDI绘图中,被标记为无效矩形的区域直到WM_PAINT消息被处理完之后才会消失。因此在绘图中应尽量避免使用Invalidate函数(该函数使整个客户区设置为无效区域),而应在多使用InvalidateRect函数具体比如你想改变某条线的线型,应首先精确计算改线的屏幕范围,然后改变其线型后调用InvalidateRect函数进行局部更新。

  1. 尽量减少不必要的绘图操作。比如二维矢量绘图中一般有一个滑动鼠标滚轮进行全图缩放的操作。其实在缩放过程中,每一次WM_MOUSEWHEEL消息的处理都必须是先把所有的绘图对象重绘一次。这个其实并没有必要。一个优化方案是通过设置一个标记,在绘图循环中(一般在复杂绘图中都把绘图对象保存在一个数组或链表中),当这个标记为TRUE时,就停止绘图,当这个标记为FALSE则不影响绘图。在处理WM_MOUSEWHEEL消息是,先设置这个标记为TRUE,然后发送一个重绘消息,设置标记为FALSE进行重绘。然后在绘图循环时先判断这个标记是否TRUE,为TRUE则退出绘图,然后截取鼠标消息,优先WM_MOUSEWHEEL消息,大致代码如下:

这样可以造成这样的效果:就是假如当进行第二次滚动,还在进行第一次滚动时的操作,就立即退出绘图循环,这样就能大大减少不必要的绘图操作。

参考文献:

  1. 绘图效率完整解决方案——三种手段提高GDI/GDI+绘图效率,作者:fyhui
  2. GDI和GDI+的应用场合思考,作者:朱金灿
  3. Agg vs. Cairo 二维绘图引擎之比较和选择,作者:张亮
  4. 用MFC如何高效地绘图
  5. GDI使用经验总结,作者:杨涛
  6. DrawCli代码中双缓冲,裁剪区技术以及坐标变换等技术分析
分享到:
评论

相关推荐

    matlab开发-彩色二维矢量野外绘图仪

    matlab开发-彩色二维矢量野外绘图仪。绘制二维矢量,根据其长度着色。

    matlab开发-3D2矢量野外绘图仪

    matlab开发-3D2矢量野外绘图仪。该函数可以根据输入符号表达式绘制三维和二维矢量场。

    VC++ 简易二维平面CAD绘图程序

    VC++ 简易二维平面CAD绘图程序

    C++编写的二维绘图软件

    实现CAD基本绘图功能

    二维平面图形设计(MFC绘图小程序)

    二维平面图形设计:可通过菜单或者工具栏按钮,选择绘画工具,画不同的平面图形(直线、圆弧、矩形、圆角矩形、圆、椭圆等);可通过颜色对话框选择不同的颜色,使所画的图形具有不同颜色;可保存文档所画的图形,并...

    Two.js---二维绘图 API

    Two.js 有一个内置的动画循环,可搭配其他动画库。Two.js 包含可伸缩矢量图形解释器,这意味着开发人员和设计人员都可以在商业应用中,如 Adobe Illustrator 中创建 SVG 元素,并把它引入 Two.js 使用场景中。

    JAD(基于Java平台二维图形辅助设计软件)-V1.0.2

    JAD(基于Java平台二维图形辅助设计软件V1.0)是一款通用的二维矢量图形绘制工具,基于Java SE平台开发的桌面应用程序,当前版本为V1.0,可以用于需要矢量图绘制的各种领域和行业。软件提供点、直线、多段线、正...

    二维CAD二次开发控件(免费版)

    《Asuo二维绘图控件v2.0》=============================================================================软件名称:《Asuo二维绘图控件》软件版本: V2.0软件作者:asuo作者邮箱:asuo@263.net软件网站:...

    c++课程设计绘图

    我自己做的mfc绘图程序,参照孙鑫的视频讲解,功能完善,界面良好,课程设计的题目,在老师那儿拿的优秀

    c#+GDI绘图ppt

    GDI+主要有二维矢量图形、图像处理和版式三部分组成 GDI+提供了存储基元自身相关信息的类和结构、存储基元绘制方式相关信息的类,以及实际进行绘制的类 GDI+ 为使用各种字体、字号和样式来显示文本这种复杂任务...

    plotutils:用于二维光栅和矢量图形的 C/C++ 库和工具-开源

    它的核心是 libplot,这是一个强大的 C/C++ 函数库,用于以多种文件格式(矢量和位图)导出二维矢量图形。 在 X Window 系统上,它还可以做二维矢量图形动画。 libplot 与设备无关,因为它的 API(应用程序编程接口...

    矢量符号SVG开源编辑器inkscape操作手册英文版

    SVG(Scalable Vector Graphics)是一种基于XML的二维矢量图形文件格式,支持无限缩放而不会失真,适用于网页、打印和多媒体等场景。它包含路径、形状、文本、滤镜及动画等多种元素。 Inkscape是一款开源、免费的...

    彩色 2D 矢量场绘图仪:绘制根据长度着色的 2D 矢量。-matlab开发

    COLORVFIELD 彩色二维矢量场绘图仪。 COLORVFIELD(X,Y,U,V) 在点 (x,y) 处绘制具有分量 (u,v) 的彩色矢量。 这些向量使用 jet 颜色图进行着色(最小的向量为蓝色,最大的向量为红色),并分为 32 个离散颜色级别。 ...

    visual graph 专业图形控件

    Visual Graph图形开发平台是的功能特点:完整而庞大的矢量图形系统 二维矢量绘图工具系统 动态图形人机界面系统(HMI) 面向对象的可扩充图形库系统 表格或报表系统 组态监控系统最佳开发工具系统 图形拓扑分析系统。...

    栅格数据结构与矢量数据结构的比较.doc

    栅格数据结构表示的是二维表面上的要素的离散化数值,每个网格对应一种属性。 网格边长决定了栅格数据的精度。 矢量数据结构 矢量数据结构是利用欧几里得几何学中的点、线、面及其组合体来表示地理实体的空 间分布...

    栅格数据结构与矢量数据结构的比较.pdf

    栅格数据结构表示的是二维表面上的要素的离散化数值,每 个网格对应一种属性。 网格边长决定了栅格数据的精度。 矢量数据结构 矢量数据结构是利用欧几里得几何学中的点、线、面及其组 合体来表示地理实体的空间分布...

    VectorControl.Net,专业矢量图形二次开发控件

    二维变换,支持缩放、扭曲、平移和旋转等二维变换,并可以启用或禁用这些操作。> 图形的成组和解组> 图形的层次调整> 支持多个图形之间的对齐> 支持多个图形之间的分布功能> 调整多个图形的尺寸以达到相同高度或宽度...

    sodacad:sodaCAD 是一种企业级基于二维矢量的绘图程序,时装设计师和制造商使用它来创建和分级服装行业中使用的图案

    ---- 关于sodaCAD ---- 一个开源图案制作 CAD 套件,具有类似于 Optitex、Tukatech 或 Gerber 的 Accumark 的功能。 sodaCAD 将支持许多高级功能,例如图案制作、分级和标记。 用户界面对于服装和缝纫产品行业的...

    图形的可缩放矢量图形 (SVG) 导出:将 3D 和 2D MATLAB 绘图转换为可缩放矢量格式 (SVG)。-matlab开发

    将 2D 和 3D Matlab 绘图转换为可缩放矢量格式 (SVG)。 此格式由 W3C ( http://www.w3.org ) 指定,可以使用 Internet 浏览器查看和打印。 添加了对超出 Matlab 功能的过滤器、剪辑和刻度线扩展的初步支持。 SVG ...

    Pencil:跨平台的二维动画软件-开源

    Pencil 是一个跨平台的开源二维动画软件。 它的首要目标是制作传统动画(cel、卡通等)。 它具有位图和矢量绘图工具、图层、相机。 使用 Pencil 制作的动画可以导出为 QuickTime。

Global site tag (gtag.js) - Google Analytics