如果您想要原始速度,最好的选择是使用 DirectX。下一个最好的方法可能是使用 C++ 中的 GDI 并提供一个托管接口来调用它。然后可能直接从 C# p/invoke 到 GDI,最后在 C# 中使用 GDI+。但是,根据您的操作,您可能看不到巨大的差异。如果您受到 GDI+ 驱动显卡速度的限制,多线程可能对您没有帮助,但如果您在计算“绘制什么”时受处理器限制,则可能会有所帮助。如果您要按顺序打印许多图像,则可以通过在单独的线程上运行预计算、渲染和打印“阶段”来获得收益。
但是,您可以采取许多措施来优化重绘速度,包括优化和折衷方案,这些方法将适用于您选择的任何渲染系统。事实上,其中大部分都源于优化代码时使用的相同原则。
你怎样才能最大限度地减少你绘制的数量?
首先,消除不必要的工作。想想你画的每一个元素——真的有必要吗?通常一个更简单的设计实际上可以看起来更好,同时节省大量的渲染工作。考虑是否可以将渐变填充替换为平面填充,或者圆角矩形是否看起来像普通矩形一样可以接受(并在丢弃之前测试这样做是否会为您的硬件带来任何速度优势!)
挑战你的假设 - 例如。 “高分辨率”要求 - 通常如果您要在染料打印机(这是一个引入一点颜色渗色的过程)或使用任何形式的抖动混合颜色的 CMYK 打印机(它有实际分辨率比打印机可以解决的点间距低得多),相对低分辨率的抗锯齿图像通常可以产生与超高分辨率图像一样好的结果。如果您要输出到 2400dpi 的黑白打印机,您可能仍然会发现 1200dpi 甚至 600dpi 是可以接受的(随着分辨率的提高,回报会越来越少,而且大多数人不会注意到 600dpi 和 2400dpi 之间的区别) .只需使用不同的源分辨率打印一些典型示例,看看结果如何。如果您可以将分辨率减半,您的渲染速度可能会提高 4 倍。
一般尽量避免过度绘制同一区域 - 如果要在区域周围绘制黑色框,可以在黑色矩形内绘制白色矩形,但这意味着将中间的所有像素填充两次。您可以通过在外部绘制 4 个黑色矩形来精确绘制框架来提高性能。相反,如果你有很多绘图图元,你能减少你绘制的图元的数量吗?例如如果要绘制很多条纹,可以交替绘制不同颜色的矩形(= 2n 个矩形),或者您可以用一种颜色填充整个背景,然后只绘制第二种颜色的矩形(= n+1 个矩形) .减少单独调用 GDI+ 方法的次数通常可以带来显着的收益,尤其是在您拥有快速图形硬件的情况下。
如果您多次绘制图像的任何部分,请考虑将其缓存(将其渲染为位图,然后在需要时将其传送到最终图像)。这个子图像越复杂,缓存它就越有可能得到回报。例如,如果您有像尺子这样的重复图案,不要将每个标尺标记绘制为单独的线 - 渲染标尺的重复部分(例如 10 行或 50 行),然后将其预渲染几次以绘制最后的统治者。
同样,避免做大量不必要的工作(例如许多 MeasureString 调用可能会预先计算一次甚至近似的值。或者,如果您要遍历很多 Y 值,请尝试通过在每个 Y 值上添加偏移量来实现迭代而不是每次都使用复数重新计算绝对位置)。
尝试“批量”绘图,以尽量减少必要的状态更改和/或绘图方法调用的次数 - 例如在继续使用下一种颜色之前,绘制一种颜色/纹理/画笔中的所有元素。使用“批量”渲染调用(例如,绘制折线图元一次,而不是调用 DrawLine 100 次)。
如果您正在执行任何逐像素操作,那么获取原始图像缓冲区并直接操作它通常比调用 GetPixel/SetPixel 方法快得多。
正如您已经提到的,您可以关闭昂贵的操作,例如抗锯齿和字体平滑,这在您的特定情况下不会有任何/太多好处。
当然,看看你正在渲染的代码 - 分析它并应用通常的优化来帮助它有效地流动。
最后,您应该考虑硬件升级是否是一种廉价而有效的解决方案 - 如果您的 PC 速度较慢且显卡低端,那么购买一个可能会获得显着收益带有更好显卡的新 PC。或者,如果图像很大,您可能会发现增加几 GB 的 RAM 可以消除虚拟内存分页开销。这听起来可能很昂贵,但有一点是,新硬件的成本/收益比投入更多资金进行额外优化工作(及其不断减少的回报)要好。