绘图的双缓冲技术
- 格式:docx
- 大小:105.95 KB
- 文档页数:12
计算机地图制图软件中图形控制措施的探讨摘要:在社会的各个领域,地图都起着至关重要的作用,但是随着科技及经济的发展,需要的地图越来越精细复杂,手工制图已经不能满足社会的需要了,计算机可以处理庞大的复杂的数据,将计算机技术引入到地图学对其建设与发展起了非常大的作用。
本文详细介绍了计算机地图制图软件中数据结构的分类及其符号化,并对利用制图软件实现图形的无级缩放、平移以及快速移动做了详细阐述。
关键词:数据结构无级缩放平移快速恢复1 引言现今的社会是信息时代,科学与计算机技术飞速发展,特别是尤个人电脑的处理能力大大地提高,使得图形处理设备快速发展及更新,计算机地图制图、地理信息系统和电子地图像雨后春笋一样迅速发展起来。
计算机地图制图运用先进的电子计算机、扫描仪、数字化仪、胶片机、绘图机、光盘等系统硬件和图形输入、识别、制图、输出等软件,从而使资料数字化、符号化以及制图自动化得以实现。
计算机地图制图(以下简称CAC)过程主要分为数据采集、数据处理与数据输出三个阶段,其中空间数据结构不仅决定了数据采集与处理的方法,还决定数字地图输出形式,因此空间数据结构在计算机地图制图的过程中有重要作用。
2 地图空间数据结构地图空间数据结构包含矢量数据结构与栅格数据结构。
矢量数据结构为点、线、面,其能够构成现实世界中的各种复杂实体,若可以把问题描述为线或者边界的时候就特别方便了;然而栅格数据的构是通过空间点密集并将其规则排列来表示整体空间现象的。
一般矢量数据的符号化是由符号化程序并依据符号库中储存的符号信息来实现的。
在其符号化前要对将要绘制的符号来编码,并形成符号的信息块以及建立符号库。
矢量数据符号化包含符号信息块方式以及程序块式。
而栅格数据符号化一般采取信息块方式,基本没有使用程序块方式的。
①栅格符号主要缺点是不能够随意的缩放。
因为缩放的时候栅格必须要用整数来表示其象素,所以缩放各部分的形变就相对较大。
②绘制点符号。
把分类后的特征码对应栅格符号的信息块调入之后并进行一定的缩放,接着在定位的轴线旋转之后将符号平移,符号的中心点平移的位置要和预订的符号定位处一致,这样就完成了绘制点符号。
卡马克卷轴算法研究摘要与关键词中文摘要对于J2ME框架下的手机游戏程序的开发,其地图滚动的重绘有多种算法,由于手机性能的限制和开发周期等其他非技术条件,需要根据情况灵活选择所需的技术。
但在及其苛刻条件下,如系统CPU资源不足,地图块尺寸较小等,会造成屏幕闪耀,帧数过低等情况,严重影响到游戏体验。
在开发中如此类问题无法绕过以及避免(指通过修改策划方案,以及程序使用的技术框架),则需要考虑使用地图缓冲绘制技术,卡马克卷轴就是一种最经典的地图缓冲绘制技术。
可有效的改善在地图绘制中的屏幕闪耀,帧数过低等情况。
English AbstractFor J2ME Mobile Phone Games under the framework of the development process, and its rolling redraw the map has a variety of algorithms, because of restrictions on mobile phone performance and development cycle and other non-technical conditions required under the circumstances required the flexibility to choose technologies. However, in its harsh conditions, such as system CPU resources are insufficient, and a smaller block size, etc., will cause the screen shine, low frames, etc., seriously affecting the gaming experience. At the development of such a category can not bypass the problem and to avoid (referring to the adoption of amendments to planning programs, as well as the technology used in the framework of the procedure), you need to consider the use of map rendering buffer, scroll Carmack is one of the most classic map buffer rendering. Can effectively improve the mapping of the screen shine, frames are too low and so on.关键词●卡马克卷轴:一种经典的地图缓冲绘制技术。
C++MFC(13)-双缓冲技术实现绘图双缓冲即在内存中创建⼀个与屏幕绘图区域⼀致的对象,先将图形绘制到内存中的这个对象上,再⼀次性将这个对象上的图形拷贝到屏幕上,这样能⼤⼤加快绘图的速度。
MARK⼀下实现步骤,略去了项⽬的绘画代码,亲测有效。
我程序中是在int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)CMainFrame::OnSize()CDC MemDC; //⾸先定义⼀个显⽰设备对象CBitmap MemBitmap;//定义⼀个位图对象 //随后建⽴与屏幕显⽰兼容的内存显⽰设备MemDC.CreateCompatibleDC(NULL); //这时还不能绘图,因为没有地⽅画 ^_^MemBitmap.CreateCompatibleBitmap(pDC,nWidth,nHeight); //建⽴⼀个与屏幕显⽰兼容的位图,⾄于位图的⼤⼩嘛,可以⽤窗⼝的⼤⼩,也可以⾃⼰定义CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap); //将位图选⼊到内存显⽰设备中MemDC.FillSolidRect(0,0,nWidth,nHeight,RGB(255,255,255)); //先⽤背景⾊将位图清除⼲净,这⾥我⽤的是⽩⾊作为背景 你也可以⽤⾃⼰应该⽤的颜⾊//绘图内容MemDC.MoveTo(……); MemDC.LineTo(……); pDC->BitBlt(0,0,nWidth,nHeight,&MemDC,0,0,SRCCOPY); //将内存中的图拷贝到屏幕上进⾏显⽰MemDC.SelectObject(pOldBit); MemBitmap.DeleteObject(); MemDC.DeleteDC();。
《1》普通绘图就是直接在我们看得到的黑板上绘图《2》双缓冲就是先在一个虚拟的黑板上画完,等用到的时候在把虚拟黑板上的图画复制到我们看得到的黑板上去;利用双缓冲的优点就是能够使画面流畅,可以想象把画好的图直接粘贴到黑板上一定比在黑板上重新画要快的多。
——————————————————————开始第一步:新建一个对话框工程第二步:添加两个按钮:一个命名为双缓冲绘图;一个命名为普通绘图;第三步:声明变量:在CMyDlg类上右击添加变量如下:CDC MyDC;CBitmap bmp;CBitmap *oldbmp;首先声明一个与窗口DC兼容的内存DC(MyDC)和两个与内存相兼容的位图(bmp,*oldbmp)第四步:在OnInitDialog()函数中添加以下代码://窗口DCCDC *dc=GetDC();//创建与窗口DC兼容的内存DC(MyDC)及位图(bmp,*oldbmp )MyDC.CreateCompatibleDC(dc);bmp.CreateCompatibleBitmap(dc,200,200);//把内存位图选进内存DC中用来保存在内存DC中绘制的图形oldbmp=MyDC.SelectObject(&bmp);//在内存DC中绘制一些小的圆形,数量要多(体现双缓存的优点)for(int i=0;i<200;i+=6)for(int j=0;j<200;j+=6)MyDC.Ellipse(i-3,j-3,i+3,j+3);第五步:右击CMyDlg类添加windows消息响应函数WM_CLOSE,添加以下代码:MyDC.SelectObject(oldbmp);bmp.DeleteObject();MyDC.DeleteDC();//选进原来的位图,删除内存位图对象和内存DC第六步:双击”双缓冲“按钮添加以下代码:GetDC()->StretchBlt(0,0,200,200,&MyDC,0,0,200,200,SRCCOPY);//把内存DC中的图形粘贴到窗口中;第七步:双击“普通绘图”按钮添加以下代码:for(int i=0;i<200;i+=6)for(int j=0;j<200;j+=6)GetDC()->Ellipse(i-3,j-3,i+3,j+3);//按普通方式在窗口中绘制和在内存DC中一样数量和大小的位图;第八步:运行程序............................先单击普通绘图按钮,大家可以看到绘图的速度有点慢再单击双缓冲绘图按钮,图像马上就显示出来了,这就是双缓冲和普通绘图的区别了______________________________________________________________________完成双缓冲技术说起来也没有那么神秘,举个形象一点的例子吧,有两张纸A和B,纸A代表屏幕,纸B代表后台缓冲,我们将所有的绘图操作都显示在纸B上,然后将纸B覆盖在纸A上,这样体现在纸A上的操作就是绘制了整张图,体现在纸B上的就是纷繁复杂的绘图操作。
GDI+测井曲线绘图中效率提升的研究作者:王宇飞赵正文李瑶来源:《数字技术与应用》2013年第03期摘要:GDI+提供了快速、简单、有效的程序开发方式。
大量测井原始数据生成测井曲线时,绘制对象的增加严重制约了GDI+的绘图效率。
双缓冲技术的使用,可以有效避免图形的闪烁;使用内存中已有图形,可以减少测井曲线的绘制过程,显著提高图形绘制效率。
关键词:测井曲线双缓冲内存图形绘图效率中图分类号:P631.84 文献标识码:A 文章编号:1007-9416(2013)03-0083-021 前言GDI(Graphics Device Interface,图形设备接口)的主要任务是负责系统与绘图程序之间的信息交换,处理所有Windows程序的图形输出。
通过GDI众多函数,软件开发人员不需要关心设备驱动及具体硬件设备,就可以将应用程序的输出转化为硬件设备上的输出,实现程序与硬件设备的隔离,方便开发工作。
GDI+是GDI的升级版本,在GDI的基础上进行了了大量的优化和改进工作,使得它的易用性更好。
GDI其中的一个好处就是用户不必知道任何关于数据怎样在设备上绘制图像的细节,GDI+更好地拓展了这一优点,GDI是一个中低层API,用户必须需要知道设备情况,而GDI+是一个高层的API,用户可以不必知道设备情况,GDI+的体系结构如图1。
此外,GDI+不但在功能上比GDI强大很多,而且在代码编写方面也要显得更加简单方便,这将使得其很快成为Windows图形图像程序开发的首选。
2 测井曲线绘制中存在问题测井是油田勘探与开发过程中确定和评价油、气层的重要方法之一,是解决地质问题的重要手段。
通过测井能直接为石油地质和工程技术人员提供各项资料和数据,以指导油田生产。
然而,通过测井设备测量出的大多是一系列离散或连续的数值型数据,同时这也是它们在数据库中的存储形式,即使经验丰富的测井解释人员要想在几百甚至几千米井深的海量测井数据中获得解释结论也是相当困难的,不利于测井数据发挥其功用。
[转载]MFC绘制动态曲线,⽤双缓冲绘图技术防闪烁先上效果图随着时间的推移,曲线向右平移,同时X轴的时间坐标跟着更新。
⼀、如何绘制动态曲线 所谓动画,都是⼀帧⼀帧的图像连续呈现在⽤户⾯前形成的。
所以如果你掌握了如何绘制静态曲线,那么学会绘制动态曲线也不远啦,只需要创建⼀个定时器(⽐如调⽤MFC中的SetTimmer函数),每隔⼀定时间(⽐如1ms),调⽤OnPaint或者OnDraw函数,绘制当前帧图像即可。
这⾥需要注意的是,绘制图像的代码需要写在OnPaint或者OnDraw函数中,因为当窗⼝失效(⽐如最⼩化)恢复后,会重新绘制当前窗⼝,窗⼝之前的⾃绘图像会丢失。
⽽把绘图代码写在OnPaint或者OnDraw中就是为了让窗⼝每次重绘时也能重绘你⾃⼰画的图像,避免出现窗⼝最⼩化再恢复后,⾃⼰画的图像丢失的尴尬情况。
另外绘制当前帧图像之前,记得⽤InvalidateRect函数清除上⼀帧图像,不然各帧图像会背景的堆叠。
⽐如我想清除窗⼝中(0,0)和(100,100)这两点确定的矩形中的图像,代码如下:CRect Rect;Rect.top = 0;Rect.left = 0;Rect.bottom = 100;Rect.right = 100;InvalidateRect(Rect); 根据上⾯的思路,我们每隔⼀定时间绘制⼀幅图像,可是如果每次绘制的图像都是完全相同的,那么图像看起来也是静态的。
如何让曲线动起来呢?我们需要为⾃⼰绘图的代码设计⼀个输⼊,即在当前时刻曲线上各个点的坐标信息。
随着时间的推移,令曲线上各个点的坐标随之变化,这样每次绘图都是基于当前时刻的曲线坐标绘制的,控制好曲线坐标的变化,也就能让你绘制的曲线乖乖的动起来。
上⾯提到了曲线上各个点的坐标信息,这个信息可以⽤多种数据结构储存,不过笔者推荐使⽤STL中的deque数据结构储存。
为什么呢?需求决定选择。
让我们先想想在绘制图像的过程中需要对这个数据进⾏哪些操作。
利用定时器和双缓冲技术在MFC中绘制动画作者:杜小甫来源:《数字技术与应用》2013年第08期摘要:对MFC中动画绘制涉及到的两个重要技术做较全面的总结和提炼,创建了一个通用性较强的动画绘制程序框架。
首先对MFC中定时器技术和双缓冲技术做出深入分析;其次创建一个动画绘制程序框架;最后通过几个动画程序验证该框架。
该程序框架已经应用在实际工作中,证明该框架是精炼有效的。
关键词:MFC 动画定时器双缓冲中图分类号:TP311.11 文献标识码:A 文章编号:1007-9416(2013)08-0129-011 定时器和双缓冲技术MFC是微软公司推出的软件开发架构[1],在MFC中绘制动画常见于各类软件开发。
动画绘制一种思路是利用循环语句加延迟函数的方式[2],另外一种思路就是利用定时器[3]定时更像图片绘制动画。
后者在绘制过程中可以响应其他事件,因此应用十分广泛。
1.1 定时器技术定时器可以向系统定时发送信号,触发OnTimer函数。
在定时器使用过程中涉及到三个常用函数,分别对应着使用定时器的三个步骤。
(1)创建定时器。
创建定时器使用SetTimer函数。
MFC中提供两个SetTimer函数,一个是全局函数,可以在程序的任意位置调用。
我们更常使用的是第二种SetTimer函数,由CWnd类重载。
函数有三个参数,分别是定时器编号、时间间隔和回调函数[4]地址。
(2)处理定时器信号。
MFC在OnTimer函数中处理定时器信号。
OnTimer函数具有一个参数,是捕捉到的定时器编号。
我们可以利用其区分不同的定时器信号,执行不同代码。
(3)销毁定时器。
定时器也会占用一定的系统资源,所以必须及时销毁不用的定时器,否则会影响系统运行效率。
MFC中使用KillTimer函数销毁定时器,该函数参数就是待销毁的定时器编号。
1.2 双缓冲技术在Windows平台上,应用程序的图像设备接口被抽象化为设备上下文(Device Content,DC)。
提⾼C#刷新效率转⾃:GDI+的双缓冲问题终于搞定了, 真是松了⼀⼝⽓!⼀直以来的误区:.Net1.1 和 .Net 2.0 在处理控件双缓冲上是有区别的。
.Net 1.1 中,使⽤:this.SetStyle(ControlStyles.DoubleBuffer, true);.Net 2.0中,使⽤:this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);怪不说⽼是提⽰参数⽆效,⼀直也不知道是这个问题,呵呵要知道,图元⽆闪烁的实现和图元的绘制⽅法没有多少关系,只是绘制⽅法可以控制图元的刷新区域,使双缓冲性能更优!导致画⾯闪烁的关键原因分析:⼀、绘制窗⼝由于⼤⼩位置状态改变进⾏重绘操作时绘图窗⼝内容或⼤⼩每改变⼀次,都要调⽤Paint事件进⾏重绘操作,该操作会使画⾯重新刷新⼀次以维持窗⼝正常显⽰。
刷新过程中会导致所有图元重新绘制,⽽各个图元的重绘操作并不会导致Paint事件发⽣,因此窗⼝的每⼀次刷新只会调⽤Paint事件⼀次。
窗⼝刷新⼀次的过程中,每⼀个图元的重绘都会⽴即显⽰到窗⼝,因此整个窗⼝中,只要是图元所在的位置,都在刷新,⽽刷新的时间是有差别的,闪烁现象⾃然会出现。
所以说,此时导致窗⼝闪烁现象的关键因素并不在于Paint事件调⽤的次数多少,⽽在于各个图元的重绘。
根据以上分析可知,当图元数⽬不多时,窗⼝刷新的位置也不多,窗⼝闪烁效果并不严重;当图元数⽬较多时,绘图窗⼝进⾏重绘的图元数量增加,绘图窗⼝每⼀次刷新都会导致较多的图元重新绘制,窗⼝的较多位置都在刷新,闪烁现象⾃然就会越来越严重。
特别是图元⽐较⼤绘制时间⽐较长时,闪烁问题会更加严重,因为时间延迟会更长。
解决上述问题的关键在于:窗⼝刷新⼀次的过程中,让所有图元同时显⽰到窗⼝。
⼆、进⾏⿏标跟踪绘制操作或者对图元进⾏变形操作时当进⾏⿏标跟踪绘制操作或者对图元进⾏变形操作时,Paint事件会频繁发⽣,这会使窗⼝的刷新次数⼤⼤增加。
基于WindML的图形开发与应用练学辉;朱佳丽;乔大雷【摘要】以电子地图显示软件开发为背景,研究了Vxworks下使用WindML3.0进行嵌入式图形开发的全过程,包括WindML的配置和加载、WindML下图形开发的总体框架等,并实现了WindML下图形窗口的创建、显示、刷新,汉字的显示,并利用双缓冲技术解决电子地图刷新时的屏幕闪烁问题.【期刊名称】《雷达与对抗》【年(卷),期】2015(035)001【总页数】4页(P65-68)【关键词】WindML图形开发;WindML配置和加载;窗口显示;双缓冲;汉字显示【作者】练学辉;朱佳丽;乔大雷【作者单位】海军驻南京地区雷达系统军事代表室,南京210003;中国船舶重工集团公司第七二四研究所,南京211153;中国船舶重工集团公司第七二四研究所,南京211153【正文语种】中文【中图分类】TP31Vxworks实时操作系统具有高实时性、高可靠性等特点,被广泛应用于工业控制、国防军事等领域。
Vxworks6.0以下版本采用的是Tornado开发工具,而Vxworks6.0以上版本集成的是Workbench开发工具。
Vxworks能够支持大多数常用的工作平台和目标处理器,除基本的功能和开发工具外,它还具有多媒体应用开发组件WindML。
WindML组件为嵌入式系统提供了基于常用设备的图形、视频以及音频技术。
Tornado 和Workbench开发工具均支持WindML组件,且Workbench支持更高的WindML版本。
本文总结了基于WindML3.0的图形开发过程,包括WindML的配置、加载及遇到的问题与解决方法,同时描述了基于WindML实现电子地图的任意缩放、平滑漫游以及名称标绘等功能的内容,主要介绍基于WindML的绘图窗口的创建、显示、刷新,双缓冲技术在电子地图显示软件中的具体应用以及汉字显示的实现。
WindML多媒体库是Tornado的可选组件之一,具有一整套Vxworks操作系统下的基本图形功能,为开发者提供了一个层次清晰、结构合理的图形开发框架。
双缓冲(DoubleBuffer)原理和使⽤⼀、双缓冲作⽤双缓冲甚⾄是多缓冲,在许多情况下都很有⽤。
⼀般需要使⽤双缓冲区的地⽅都是由于“⽣产者”和“消费者”供需不⼀致所造成的。
这样的情况在很多地⽅后可能会发⽣,使⽤多缓冲可以很好的解决。
我举⼏个常见的例⼦:例 1. 在⽹络传输过程中数据的接收,有时可能数据来的太快来不及接收导致数据丢失。
这是由于“发送者”和“接收者”速度不⼀致所致,在他们之间安排⼀个或多个缓冲区来存放来不及接收的数据,让速度较慢的“接收者”可以慢慢地取完数据不⾄于丢失。
例2. 再如,计算机中的三级缓存结构:外存(硬盘)、内存、⾼速缓存(介于CPU和内存之间,可能由多级)。
从左到右他们的存储容量不断减⼩,但速度不断提升,当然价格也是越来越贵。
作为“⽣产者”的 CPU 处理速度很快,⽽内存存取速度相对CPU较慢,如果直接在内存中存取数据,他们的速度不⼀致会导致 CPU 能⼒下降。
因此在他们之间⼜增加的⾼速缓存来作为缓冲区平衡⼆者速度上的差异。
例3. 在图形图像显⽰过程中,计算机从显⽰缓冲区取数据然后显⽰,很多图形的操作都很复杂需要⼤量的计算,很难访问⼀次显⽰缓冲区就能写⼊待显⽰的完整图形数据,通常需要多次访问显⽰缓冲区,每次访问时写⼊最新计算的图形数据。
⽽这样造成的后果是⼀个需要复杂计算的图形,你看到的效果可能是⼀部分⼀部分地显⽰出来的,造成很⼤的闪烁不连贯。
⽽使⽤双缓冲,可以使你先将计算的中间结果存放在另⼀个缓冲区中,但全部的计算结束,该缓冲区已经存储了完整的图形之后,再将该缓冲区的图形数据⼀次性复制到显⽰缓冲区。
例1 中使⽤双缓冲是为了防⽌数据丢失,例2 中使⽤双缓冲是为了提⾼ CPU 的处理效率,⽽例3使⽤双缓冲是为了防⽌显⽰图形时的闪烁延迟等不良体验。
⼆、双缓冲原理这⾥,主要以双缓冲在图形图像显⽰中的应⽤做说明。
上⾯例3中提到了双缓冲的主要原理,这⾥通过⼀个图再次理解⼀下:图 1 双缓冲⽰意图注意,显⽰缓冲区是和显⽰器⼀起的,显⽰器只负责从显⽰缓冲区取数据显⽰。
[Qt2D绘图]-06QPainter的复合模式双缓冲绘图绘图中的其他问题本篇读书笔记主要记录QPainter的复合模式&&双缓冲绘图&&绘图中的其他问题⼤纲:复合模式双缓冲绘图绘图中的其他问题重绘事件剪切读⼊和写⼊图像播放GIF渲染SVG复合模式QPainter提供了复合模式(Composition Modes)来定义如何完成数字图像的复合,即如何将源图像的像素和⽬标图像的像素进⾏合并。
QPainter 提供的常⽤复合模式及其效果如下⾯截图所⽰,所有的复合模式可以在QPainter的帮助⽂档中进⾏查看。
最普通的类型是SourceOver(不设置的话默认是这个)(通常被称为alpha混合),就是正在绘制的源像素混合在已经绘制的⽬标像素上,源像素的alpha分量定义了它的透明度,这样源图像就会以透明效果在⽬标图像上进⾏显⽰。
若绘图设备是QImage,图像的格式⼀定要指定为QImage::Format_ARGB32_Premultiplied或者Format_ARGB32,不然复合模式就不会产⽣任何效果。
当设置了复合模式,它就会应⽤到所有的绘图操作中,如画笔、画刷、渐变和pixmap/image绘制等。
演⽰书上的代码:void Widget::paintEvent(QPaintEvent *){QPainter painter;QImage image(400,300,QImage::Format_ARGB32_Premultiplied);// 使⽤绘图设备,绘制到绘图设备上painter.begin(&image);// 绘制⼀个矩形painter.setBrush(Qt::green);painter.drawRect(100,50,200,200);//在四个⾓分别绘制⼀个矩形,使⽤不同的复合模式(composition)painter.setBrush(QColor(0,0,255,150));//composition没有设置则使⽤默认的SourceOverpainter.drawRect(50,0,100,100);//QPainter::CompositionMode_SourceInpainter.setCompositionMode(QPainter::CompositionMode_SourceIn);painter.drawRect(250,0,100,100);//QPainter::CompositionMode_DestinationOverpainter.setCompositionMode(QPainter::CompositionMode_DestinationOver);painter.drawRect(50,200,100,100);//QPainter::CompositionMode_Xorpainter.setCompositionMode(QPainter::CompositionMode_Xor);painter.drawRect(250,200,100,100);painter.end();// 绘制到当前部件(当前绘图设备是QWidget的⼦类,也就是部件)painter.begin(this);painter.drawImage(0,0,image);}效果图:双缓冲绘图所谓双缓冲(double-buffers)绘图,就是在进⾏绘制时,先将所有内容都绘制到⼀个绘图设备(如QPixmap)上,然后再将整个图像绘制到部件上显⽰出来。
基于MFC的绘图软件设计与实现作者:黄琛来源:《电脑知识与技术》2013年第10期摘要:MFC作为C++封装技术的主体代表,继承了C++在绘图方面的优点,可以较好的把抽象的变得直观,该文主要是介绍一款基于MFC,同时程序与Windows系统中的信息交互主要是运用到图形设备接口(GDI)编程技术的绘图软件的设计与实现过程,也为办公中的小型绘图提供了解决方案。
关键词:MFC;绘图;GDI;软件设计;解决方案中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2013)10-2345-041 概述绘图软件可以说是一个用来作图的软件,通常是指计算机中的一组用于绘图和显示图片的程序,它的开发语言和技术已经应用很广泛。
绘图软件的开发一般是高级算法语言,以子程序的方式进行实现,其中,它的每个子程序是独立有绘图功能。
简而言之,绘图软件就是将我们通常所见的所需要的图像抽象成线条,运用高级算法编程技术对这些点和线条进行组合,加色,保存,编辑等的软件。
MFC(Microsoft Foundation Classes),是一个微软公司提供的类库(class libraries),以C++类的形式封装了Windows的API,并且包含一个应用程序框架,以减少应用程序开发人员的工作量。
运用MFC所包含的控件和类结合Windows GDI+技术实现一个绘图软件,既可以达到绘图的功能又能减少软件开发人员的工作量,该文接下来就介绍了这样一款绘图软件的设计及实现过程。
2 软件原理2.1 GDI+技术原理GDI+从Windows系统中开始引入一系列的技术来实现常用的功能,这些是基于之前比较老的GDI版本。
GDI+加强了可视化的属性,最主要的就是操作界面和图像的边界透明技术,同时改进旧版本的GDi之后,能够提供多维的矢量图形和直接实现了各种格式图片之间的相互转换,主要的格式包括JPEG,GIF,BMP,JPG等。
它还有一大改进就是能够生成多种格式的图片,当然也不仅仅局限于图片,比如我们常说的动画Flash也可以生成。
绘图的双缓冲技术
简介
幸运的是当编写一个典型的Windows 窗体程序时,窗体和控件的绘制、效果等操作是不需要特别加以考虑的。
这是为什么呢?因为通过使用.Net 框架,开发人员可以拖动一系列的控件到窗体上,并书写一些简单的与事件相关
联的代码然后在IDE中按F5,一个完完全全的窗体程序就诞生了!所有控件都
将自己绘制自己,窗体或者控件的大小和缩放都调整自如。
在这里经常会用到的,且需要引起一点注意的就是控件效果。
游戏,自定义图表控件以及屏幕保
护程序的编写会需要程序员额外撰写用于响应Paint 事件的代码。
本文针对那些Windows 窗体开发人员并有助于他们在应用程序编制过程中使用简单的绘图技术。
首先,我们会讨论一些基本的绘图概念。
到底谁在负责
进行绘制操作?Windows 窗体程序是如何知道何时该进行绘制的?那些绘制代码究竟被放置在哪里?之后,还将介绍图像绘制的双重缓冲区技术,你将会看
到它是怎样工作的,怎样通过一个方法来实现缓存和实际显示的图像间的交替。
最后,我们将会探讨”智能无效区域”,实际就是仅仅重绘或者清除应用程序
窗体上的无效部分,加快程序的显示和响应速度。
希望这些概念和技术能够引
导读者阅读完本文,并且有助于更快和更有效的开发Windows 窗体程序。
Windows 窗体使用GDI+图像引擎,在本文中的所有绘图代码都会涉及使用托管的.Net 框架来操纵和使用Windows GDI+图像引擎。
尽管本文用于基本的窗体绘图操作,但是它同样提供了快速的、有效的且
有助于提高程序性能的技术和方法。
所以,在通读本文之前建议读者对.Net框
架有个基本的了解,包括Windows 窗体事件处理、简单的GDI+对象譬如Line,Pen和Brush等。
熟悉Visual Basic .Net或者C#编程语言。
概念
Windows 应用程序是自己负责绘制的,当一个窗体”不干净”了,也就是
说窗体改变了大小,或者部分被其它程序窗体遮盖,或者从最小化状态恢复时,程序都会收到需要绘制的信息。
Windows把这种”不干净”状态称为”无效的(Invalidated)”状态,我们理解为:需要重绘,当Windows 窗体程序需要重
绘窗体时它会从Windows消息队列中获取绘制的信息。
这个信息经过.Net框架
封装然后传递到窗体的PaintBackground 和Paint 事件中去,在上述事
件中适当的书写专门用于绘制的代码即可。
简单的绘图示例如下:
using System;
using System.Drawing;
using System.Windows.Forms;
public class BasicX : Form.
{
public BasicX()
{
InitializeComponent();
}
private void BasicX_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
Pen p = new Pen(Color.Red);
int width = ClientRectangle.Width;
int height= ClientRectangle.Height;
g.DrawLine(p, 0,0, width, height);
g.DrawLine(p, 0, height, width, 0);
p.Dispose();
}
private void InitializeComponent()
{
this.SetStyle(ControlStyles.ResizeRedraw, true);
this.ClientSize = new System.Drawing.Size(300, 300);
this.Text = "BasicX";
this.Paint += new PaintEventHandler(this.BasicX_Paint);
}
[System.STAThreadAttribute()]
public static void Main()
{
Application.Run(new BasicX());
}
}
上述代码分成两个基本的步骤来创建示例程序。
首
先InitializeComponent 方法包含一些属性的设置和附加窗体Paint 事
件的处理过程。
注意,在方法中控件的样式也同时被设置,设置控件的样式也
是自定义Windows 窗体及控件行为的一种有效途径,譬如:控件的"ResizeRedraw"属性指示当窗体的大小变化发生以后需要对其完全进行重绘,
也就是说重绘时总是需要对整个窗体的客户区域进行重绘。
窗体的“客户区域”是指除了标题栏和边框的所有窗体区域。
可以进行一个有趣的试验,取消该控
件的属性然后再运行程序,我们可以很明显的看出为什么该属性会被经常的设置,因为窗体调整大小后的无效区域根本不会被重绘。
好了,我们需要注意一下BasicX_Paint方法,正如先前所提到的,
Paint 事件在程序需要重绘时被激活,程序窗体利用Paint事件来负责回应需要重绘的系统消息,BasicX_Paint方法的调用需要一个对象sender 和一个PaintEventArgs类型的变量,PaintEventArgs类的实例或称之为变量 e 封
装了两个重要的数据,第一个就是窗体的Graphics 对象,该对象表示窗体
可绘制的表面也称之为画布用于绘制诸如线、文本以及图像等,第二个数据就
是ClipRectangle,该Rectangle对象表示窗体上无效的的矩形范围,或者说
就是窗体需要重绘的区域。
记住,当窗体的ResizeRedDraw设置后,调整大小
后该ClipRectangle的大小实际就等于窗体整个客户区域的大小,或者是被其
它程序窗体遮盖的那部分剪切区域。
关于部分剪切区域的用处我们会在智能重
绘章节作更详细的阐述。
BasicX 示例程序的运行界面。