gpt4 book ai didi

c# - Winforms:如何加速 Invalidate()?

转载 作者:太空狗 更新时间:2023-10-29 18:24:17 24 4
gpt4 key购买 nike

我正在 GDI+ 中开发保留模式绘图应用程序。该应用程序可以在 Canvas 上绘制简单的形状并执行基本编辑。执行此操作的数学运算针对最后一个字节进行了优化,这不是问题。我正在使用内置 Controlstyles.DoubleBuffer 的面板上绘图。

现在,如果我在大显示器(在我的例子中是高清显示器)上最大化运行我的应用程序,就会出现问题。如果我尝试从(大) Canvas 的一个角到对角线的另一角画一条线,它会开始滞后并且 CPU 会升高。

我的应用程序中的每个图形对象都有一个边界框。因此,当我使从最大化应用程序的一个角到对角线的对角线的边界框无效时,该边界框实际上与 Canvas 一样大。当用户画一条线时,边界框的这种无效因此发生在 mousemove 事件上,并且有明显的滞后可见。如果线条是 Canvas 上的唯一对象,也会存在这种延迟。

我尝试以多种方式对此进行优化。如果我画一条较短的线,CPU 和延迟就会下降。如果我删除 Invalidate() 并保留所有其他代码,应用程序会很快。如果我使用一个区域(只跨越图形)而不是边界框来使它无效,它也一样慢。如果我将边界框拆分为一系列背靠背的较小框,从而减少无效区域,则看不到明显的性能提升。

所以我在这里不知所措。如何加快失效速度?

附带说明一下,Paint.Net 和 Mspaint 都存在相同的缺点。然而,Word 和 PowerPoint 似乎能够像上面描述的那样画一条线,没有延迟,也没有任何 CPU 负载。这样就有可能达到预期的效果,问题是如何?

最佳答案

对于像线条这样的基本显示项目,如果您绝对必须在每个绘制周期都使它们的整个边界无效,您应该考虑将它们分成几个部分。

原因是 GDI+(以及 GDI 本身)使矩形区域无效,正如您用边界框指定的那样。您可以通过测试一些水平和垂直线与斜率与显示区域的外观相似的线来亲自验证这一点。

那么,假设您的 Canvas 是 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)

a 640x480 extent with 4 equal sized boxes carved behind a line drawn across the diagonal

或者,您可能需要考虑重写您的更新,而不是指定边界框,以便您只绘制与必须更新的区域匹配的项目部分。这实际上取决于有多少对象需要参与绘制更新。如果给定帧中有数千个对象,您可能会考虑忽略所有无效区域并重新绘制整个场景。

关于c# - Winforms:如何加速 Invalidate()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/957573/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com