.NET GDI +绘图性能

时间:2012-08-25 13:43:42

标签: .net drawing gdi

我需要绘制大约1000行。这些线每秒变化约25次(因此,每秒25000行)。在这样做时我可以使用什么来获得可接受的性能?我不想使用directX调用,因为这个软件也需要在没有directX的服务器上运行。

我试图这样做的两种不同的方式,但给了我一个融化的CPU:

Setup1 - 标准.NET调用:

  • 双缓冲面板
  • 绘制内存位图(使用Graphics.DrawLine清除和重绘行)
  • 使用Graphics.DrawImageUnscaled
  • 将位图复制到面板
  • profiler说这两个图形调用是瓶颈

Setup2 - ddimport调用gdi:

  • 双缓冲面板
  • 使用MoveToEx和来自gdi的LineTo绘制内存位图
  • 使用BitBlt
  • 将位图复制到面板
  • profiler说这些非托管呼叫是瓶颈

如果我使用WPF而不是Winforms,性能会提高吗?或者是使用directX或第三方库的唯一方法吗?

干杯

3 个答案:

答案 0 :(得分:0)

呼叫开销可能是限制因素。在vanilla GDI中,有一个PolyPolyline函数可以让你在一次调用中绘制很多行。如果您的所有线路都已连接,那么还有一个更简单的Polyline功能。我假设有GDI +等价物。我会跟那些人描述一下。即使将坐标捆绑到这些函数所需的数组中也需要一些工作,它可能比单个线条绘制函数的〜1000次调用快。

答案 1 :(得分:0)

如果行数固定:

使用WPF并将一行添加到画布。

每次打勾,根据需要更新行的末尾。您也可以更改其他属性。

我试试这个,因为这是在不直接使用DirectX的情况下接近DirectX的最简单方法。

在任何情况下:在没有合适硬件的服务器上进行这么多图形操作总是很痛苦。

答案 2 :(得分:0)

我能给出的唯一建议是,您似乎可以直接访问硬件,因此请使用标准的双缓冲方法。如果您的硬件支持它,或者只是像准备绘制的位图集合那样的内存队列,可能结合多线程,请记住处理器可以在执行一次IO操作所需的时间内完成数千次内存操作(屏幕绘制)。在达到某个“缓冲区大小”(集合大小)之后,你可以真正地拥有一个获取数据并转换到内存表面(如果你想要的位图)并继续按顺序添加到泛型集合的进程可以说,对于接下来的5分钟图像,可以对其进行编码,等待该过程使用面板消耗了更多的集合。然后在OnPaint等效面板中,它从堆栈底部获取一个内存表面,并从集合底部用一个内存表面交换出来。您可以为具有绘图任务的线程提供更多处理优先级,因为另一个线程自然会更快。请记住使用不同的线程锁定内存表面的集合,以便它的线程安全。祝你好运。