在C#中快速复制GUI?

时间:2014-01-17 11:31:08

标签: c# winforms performance winapi graphics

现在我正在通过WinApi中的BitBlt将窗口图形从一个窗口复制到另一个窗口。我想知道在C#中是否还有其他快速/更快的方法可以做同样的事情。

关键字效果。如果我应该继续使用WinApi,我会在内存中保存HDC以便快速绘制,如果.NET Framework有其他可能性,我可能会保留Graphics个对象。现在,当我需要复制~1920x1080的窗口时,我有点慢。

那么如何在C#中提升gui复制的性能呢?
我只是想知道我是否能比这更好。显式硬件加速(OpenGL,DirectX)在我看来不是我的兴趣。我决定保持纯.NET + WinApi。

// example to copy desktop to window
Graphics g = Graphics.FromHwnd(Handle);
IntPtr dc = g.GetHdc();
IntPtr dc0 = Windows.GetWindowDC(Windows.GetDesktopWindow());
Windows.BitBlt(dc, 0, 0, Width, Height, dc0, 0, 0, Windows.SRCCOPY);
// clean up of DCs and Graphics left out

汉斯的问题:

  • 它有多慢?
    • 太慢了。感觉(非常)僵硬。
  • 需要多快?
    • 软件不能感觉慢。
  • 为什么重要?
    • 软件的用户友好性。
  • 硬件是什么样的?
    • 任何随机PC。
  • 为什么不能用更好的硬件来解决它?
    • 这只是在Windows机器上运行的软件。你不会为你的旧版本运行速度慢的随机软件购买一台新PC吗?

1 个答案:

答案 0 :(得分:1)

获得更好的视频卡!

无论您是从本机代码还是通过.Net访问它,GDI的重点在于它抽象出图形子系统的细节。缺点是blitting等低级操作掌握在图形驱动程序编写者手中。你可以放心地假设这些都是尽可能优化的(毕竟,视频卡制造商希望让他们的卡看起来最好)。

与操作本身所花费的时间相比,使用.Net包装器而不是使用本机调用的开销直接变得微不足道,因此您不会获得太多收益。

您的代码正在进行非缩放,没有混合副本,这可能是复制图像的最快方法。

当然,您应该分析代码,看看您对代码所做的任何更改会产生什么影响。

那么问题是为什么要将这么大的图像从一个窗口复制到另一个窗口?你控制两个窗口的内容吗?

<强>更新

如果您控制两个窗口,为什么不绘制到单个表面然后将它们两个窗口进行操作?这应该取代通过两次写操作从视频卡读取数据(即从一个窗口到另一个窗口的blitting)的通常昂贵的操作。这只是一个想法,可能不起作用,但你需要时间数据,看它是否有任何区别。