Ped*_*ery 8 .net c# gdi+ gdi winforms
我正在GDI +中开发一个保留模式绘图应用程序.应用程序可以将简单的形状绘制到画布并执行基本编辑.执行此操作的数学运算优化到最后一个字节,不是问题.我正在使用内置的Controlstyles.DoubleBuffer绘制一个面板.
现在,如果我在大显示器上运行我的应用程序最大化(在我的情况下为HD),我的问题就出现了.如果我尝试从(大)画布的一角绘制一条线到对角线的另一角,它将开始滞后并且CPU变高.
我的应用中的每个图形对象都有一个边界框.因此,当我使从最大化应用程序的一个角落到对面角落的行的边界框无效时,该边界框几乎与画布一样大.当用户绘制一条线时,这个边界框的失效因此发生在mousemove事件上,并且有明显的滞后可见.如果线是画布上的唯一对象,则也存在此延迟.
我试图在很多方面对此进行优化.如果我画一条较短的线,CPU和滞后就会下降.如果我删除Invalidate()并保留所有其他代码,该应用程序很快.如果我使用Region(仅跨越图形)来使invalidate而不是boundingbox失效,那就慢了.如果我将边界框拆分成一系列背靠背的小方框,从而减少了无效区域,则无法看到可见的性能增益.
因此,我在这里不知所措.如何加快失效?
另外,Paint.Net和Mspaint都有同样的缺点.然而,Word和PowerPoint似乎能够如上所述绘制一条线,没有延迟,也没有CPU负载.因此有可能达到预期的效果,问题是如何?
对于像线条这样的基本显示项目,如果绝对必须使每个绘图周期的整个边界无效,则应考虑将它们分成几个部分.
原因是GDI +(以及GDI本身)使矩形形状的区域无效,就像您使用边界框指定的那样.您可以通过测试一些水平和垂直线与斜率与显示区域方面相似的线来自行验证.
所以,假设你的画布是640x480.如果你画一条从0,0到639,479的线; Invalidate()将使整个区域从顶部的0,0到639,0无效,到底部的0,479到639,479.例如,从0,100到639,100的水平线导致矩形仅高1像素.
区域将具有完全相同的问题,因为区域被视为组合在一起的水平范围集合.因此,对于从一个角落到另一个角落的大对角线,为了匹配您已设置的边界框,区域必须指定每条垂直线上的每组像素或整个边界框.
所以作为一个解决方案,如果你有一个非常大的线,将它分成四分之一或八分之一,性能应该大大增加.修改上面的例子,如果你只将两部分分成两半 - 你将把无效区域总数减少到0,0 x 319,239加上320,240 x 639,479.
这是四分之一分裂的视觉示例.粉红色区域是无效的.不幸的是,SO不会让我发布图片或超过1个链接,但这应该足以解释一切.
(四分之一的线分割,总无效区域是表面的1/4)
一个640x480的范围,4个相同大小的盒子刻在对角线上绘制的一条线后面
或者,您可能需要考虑重写更新,而不是指定边界框,以便只绘制与必须更新的区域匹配的项目部分.这实际上取决于需要参与绘制更新的对象数量.如果给定帧中有数千个对象,则可以考虑忽略所有无效区域并重新绘制整个场景.