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

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

网上有篇文章:绘图效率完整解决方案——三种手段提高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消息,大致代码如下:

jpg改rar

2D绘图引擎比较的更多相关文章

  1. iOS 2D绘图 (Quartz 2D) 概述

    本篇博客原文地址:http://blog.csdn.net/hello_hwc?viewmode=list 由于自己的项目需要,从网络上下载了许多关于绘制图形的demo,只是用在自己的项目中,很多地方 ...

  2. iOS 2D绘图详解(Quartz 2D)之概述

    前言:最近在研究自定义控件,由于想要彻底的定制控件的视图还是要继承UIView,虽然对CALayer及其子类很熟练,但是对Quartz 2D这个强大的框架仍然概念模棱两可.于是,决定学习下,暂定7篇文 ...

  3. Quartz-2D绘图之概览

    最近公司新项目需求要把数据图形化,趁着这个机会,重温了下Quarts-2D这个强大的跨平台2D绘图引擎. 一.Quartz概述 1.Quartz 2D是一个二维的绘图引擎,支持iOS和Mac OS平台 ...

  4. Core Graphics框架 利用Quartz 2D绘图

    首先,什么是Core Graphics和Quartz 2D? Core Graphics:是基于Quartz 2D绘图引擎的一个C语言的API绘图框架.它也是iOS开发中最基本的框架(Framewor ...

  5. 【转 | 侵删】2D 绘图技术中的坐标系统与坐标变换

    本文介绍在 2D 绘图技术中的坐标系统和坐标变换的相关知识.同时介绍 Kity 在这方面提供的 API .希望这些知识对于需要进行图形应用开发的同学会有所帮助. 锤子的故事 很久以前,有一个画家,他很 ...

  6. Agg vs. Cairo 二维绘图引擎之比较和选择 .

    Agg vs. Cairo 二维绘图引擎之比较和选择 cheungmine 当今时代对于作为二维图形软件开发者, 是幸运的.因为除了Windows GDI/GDI+之外,我们还有很多其他的选择.而且这 ...

  7. iOS基础 - Quartz 2D绘图

    一.Quartz 2D Quartz 2D是一个二维图形绘制引擎,支持iOS环境和Mac OS X环境. Quartz 2D以PDF的规范为基础的图形库,用来绘制二维文字和图形,允许相同的绘图指令在任 ...

  8. HTML5之2D物理引擎 Box2D for javascript Games 系列 翻外篇--如何结合createJS应用box2d.js

    太久没有更新了,新年回来工作,突然有收到网友的邮件提问,居然还有人在关注,惭愧,找了下电脑上还有一点儿存着,顺便先发这一个番外篇吧,好歹可以看到真实的效果,等我考完英语,一定会更新下一章," ...

  9. HTML5之2D物理引擎 Box2D for javascript Games 系列 第一部分

    我要的是能在H5页面上跑的javascript版的Box2D啊!!! 最近想学习Javascript版本的Box2D JS物理引擎,无奈搜了半天也没找到相对比较系统的资料 官方网站也只是简单的介绍,A ...

随机推荐

  1. 类型转换运算符、*运算符重载、->运算符重载、operator new 和 operator delete

    一.类型转换运算符 必须是成员函数,不能是友元函数 没有参数 不能指定返回类型 函数原型:operator 类型名();  C++ Code  1 2 3 4 5 6 7 8 9 10 11 12 1 ...

  2. STL中map错误用法一例

    [GBK]0G's fans( me ) 13:34:26typedef struct _TX_DATA{ int len; unsigned char buff[0x100]; } TX_DATA, ...

  3. JEECG 简单实例讲解权限控制

    业务背景:某公司要实现一个日志系统,用来了解员工的工作量饱和情况. 需求: 1.角色分为:员工.经理 两种. 2.员工每天在日志系统中填报工作总结,然后经理进行点评. 3.表单内容包含:姓名.日期.工 ...

  4. [转]sql:除非另外还指定了 TOP 或 FOR XML,否则,ORDER BY 子句在视图、内联函数、派生表、子查询

    执行sql语句: select * from ( select * from tab where ID>20 order by userID desc ) as a order by date ...

  5. Android Studio 使用感受 错误解决

    刚到公司不久,公司叫我用Android studio软件,曾经一直在用的是eclipse ADT.突然接触到的新名词让我有点适应只是来. 好吧,既然是公司要求,肯定有它的道理.就从网上下载了它的安装包 ...

  6. plink参数说明

    Plink: command-line connection utilityRelease 0.67Usage: plink [options] [user@]host [command]       ...

  7. atitit..主流 浏览器 js 引擎 内核 市场份额 attialx总结vOa9

    atitit..主流 浏览器 js 引擎  内核 市场份额 attialx总结vOa9 1. 浏览器内核 1 2. 浏览器的主要组件包括: 2 2.1. 主要组件体系结构 2 2.2. WebCore ...

  8. 32位嵌入式微处理器(processor)一览

    32位嵌入式微处理器(processor)一览 由于嵌入式系统的专用型与定制性,与全球PC市场不同,没有一种微处理器或者微处理器公司可以主导嵌入式系统.本文分析了当前市场上主流的一些32位嵌入式微处理 ...

  9. PaaS 平台的网络需求

    在使用 Docker 构建 PaaS 平台的过程中,我们首先遇到的问题是需要选择一个满足需求的网络模型: 让每个容器拥有自己的网络栈,特别是独立的 IP 地址 能够进行跨服务器的容器间通讯,同时不依赖 ...

  10. linux中录屏工具byzanz

    linux中录屏工具byzanz: 1.安装 sudo apt install byzanz 2.使用 help:byzanz-record --help 配合xwininfo使用--xwininfo ...