现在我正在通过 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 机器上运行的软件。您不会为了一个在旧电脑上运行缓慢的随机软件而购买新电脑吗?
最佳答案
获得更好的视频卡!
无论您是从 native 代码还是通过 .Net 访问 GDI,GDI 的全部意义在于它抽象了图形子系统的细节。缺点是低级操作(如 blitting)掌握在图形驱动程序编写者手中。您可以放心地假设这些都是尽可能优化的(毕竟,视频卡制造商希望让他们的卡看起来最好)。
与执行操作本身所花费的时间相比,使用 .Net 包装器而不是直接使用 native 调用的开销微不足道,因此您实际上不会获得太多 yield 。
您的代码正在执行非缩放、无混合复制,这可能是复制图像的最快方法。
当然,您应该分析代码以查看您对代码所做的任何更改会产生什么影响。
那么问题是为什么要将如此大的图像从一个窗口复制到另一个窗口?您控制两个窗口的内容吗?
更新
如果您控制两个窗口,为什么不绘制到一个表面,然后将其 blit 到两个窗口?这应该用两次写入操作代替从视频卡读取数据(即从一个窗口到另一个窗口)的通常昂贵的操作。这只是一个想法,可能行不通,但您需要计时数据来查看它是否有任何不同。
关于c# - 在 C# 中快速复制 GUI?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21184889/