- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
C#高效绘图
来源:/suncherrydream/article/details
双缓冲技术
双缓冲是将图片在显示到DC前,现在要内存建一个DC,也就是用于存储这张图片的内存区,然后在将这部分update到你要显示的地方
这样,可以防止画面抖动很大
这样和你说吧,如果要实现你要的效果,你必须用指针访问内存
比如,把程序声明成unsafe的,然后按照上面的操作进行
?
this.clear(this.BackColor)不行的 invalidate(),闪的厉害 所以不行
?
我再来详细解释一下刚才实现双缓冲的具体步骤:
?
1、?? 在内存中建立一块“虚拟画布”:
Bitmap?? bmp?? =?? new?? Bitmap(600,?? 600);
2、?? 获取这块内存画布的Graphics引用:
Graphics?? g?? =?? Graphics.FromImage(bmp);
3、?? 在这块内存画布上绘图:
g.FillEllipse(brush,?? i?? *?? 10,?? j?? *?? 10,?? 10,?? 10);
4、将内存画布画到窗口中
this.CreateGraphics().DrawImage(bmp,?? 0,?? 0);
重点:
现在的cpu飞快,其实数学计算一般很快,cpu大部分时间是在处理绘图,而绘图有三种境界:1每次重绘整体Invalidate()
?2每次局部绘制Invalidate(Rect);
????? 3有选择的局部绘制。
不能说,一定是第三种方式好,得视情况,境界高程序肯定就复杂,如果对效率要求不高或者绘图量小当然直接用第一种方式。然而,稍微专业点的绘图程序,第一第二种方式肯定满足不了要求,必须选用第三种方式。而第三种方式的手段多样,也得根据实际情况拿相应的解决之道。这里讲解一般的三种手段,他们可以联合使用。
1. 缓存——Bitmap或者DoubleBuffer。缓存就是先把绘制的图形绘制到一张内存位图上,然后在一次性的贴位图,他可以提高绘图速度,也能避免闪烁。DoubleBuffer=true是C#窗体的属性,设置了此属性估计系统本身会起用无效区的内存位图缓存,而不需要程序员Bitmap处理。
2. 合理利用无效区域。无效区域就是系统保存当前变化需要重绘的区域,可以在OnPaint()中,e.ClipRectangle(e.ClipRectangle.X)直接获得,也可以通过其他方式获得。Windows系统只会重绘无效区域内的绘图信息,然而我们用户的绘制代码一般是绘制整个区域的,很多时候无效区域只是一小部分区域,虽然执行了所有的绘图代码,但是Windows系统只会重新更新无效区域内的绘图。这里有两个利用点:
1用户请求重绘时,只请求重绘指定区域的,而不是整个区域,如Invalidate(Rect);
2在用户绘图代码
Graphics g; g.DrawLine\g.DrawString\g.FillRectangle...前,先判断绘图的内容是否在无效区域,如果不是就不直接g.Draw...绘图代码。
3. 直接贴图。一般绘图或者重绘是Windows根据无效区域绘制的,如果在鼠标移动时需要重绘通过Windows系统处理Paint消息,有时满足不了要求,
比如①鼠标移动绘制十字测量线就得用异或线而不是Paint消息,
又比如②鼠标移动绘制跟随的信息提示框需要频繁擦除上次覆盖的背景,
又比如③台球滚动时台球与球桌背景的关系。
类似的这些问题如何解决?首先肯定不能利用Windows原来的绘图机制。其中一种解决方式是,不断的帧间变化区域贴内存位图——②中的信息框每次鼠标位置变化时可以重新g.Draw...或者贴早生成的信息框内存位图,②中被信息框覆盖的背景应该把本来的大背景截取此需要擦除区域的位置大小位图贴回来就是擦除背景了。由于每次大背景发生变化时,都应会重新生成大背景内存位图,所以可以是变化的背景。
这三种方式可以一起使用,应该可以解决中等的绘图项目的效率问题。中大型的绘图,必须记住两点1只绘制电脑屏幕能
显示的部分;2只绘制变化的部分。
?
?
C#GDI+双缓冲高效绘图
Rectangle rectangle =? e.ClipRectangle;//取出次窗体或者画布的有效区的矩形区域
BufferedGraphicsContext GraphicsContext = BufferedGraphicsManager.Current;//获取程序住缓冲区域的BufferedGraphicsContext(双缓存类,此类用于提供双缓冲的功能)对象
BufferedGraphics myBuffer = GraphicsCon
文档评论(0)