C# WinForms - 任何人都知道 C# GDI 库不是 SLOW GDI+
Posted
技术标签:
【中文标题】C# WinForms - 任何人都知道 C# GDI 库不是 SLOW GDI+【英文标题】:C# WinForms - Anyone know of a C# GDI library not SLOW GDI+ 【发布时间】:2011-09-17 12:39:14 【问题描述】:GDI+ 非常慢,几乎完全是软件,而 GDI 是高度硬件加速的。 GDI+ 是在 WinForms 上使用的 Graphics 类,它太慢了。
有没有人制作了一个 .NET GDI 库以便我们加快速度?
[编辑] 很多人都在推荐 OpenGL/DirectX。我的一个要求是客户端兼容性,尤其是远程桌面。 AFAIK 远程桌面不支持开箱即用的 OGL/DirectX。[/EDIT]
【问题讨论】:
GDI+ 使用 GDI。如果需要直接使用GDI,请使用c或c++。 GDI+ 让你这么慢,你想做什么?除了绘制位图外,我一直发现它非常快,在这种情况下,您可以使用 PInvoke BitBlt。 您能否更具体地说明 GDI 的哪些部分正在减慢您的速度? @Paul Sasik:是的,或者,如果您需要直接访问内存中的图像,只需调用 LockBits 并获取指针。 特别是我正在绘制网格和可能的图表(用于金融系统)典型的客户有 4 台显示器,我的很多窗口在 2 - 4 台显示器上都是全屏的 【参考方案1】:GDI+ 中的文本渲染比 GDI 慢。微软在 .NET 1.1 之后意识到了这一点。
这就是为什么 .NET 2.0 包含一个新的 TextRenderer
类来包装 GDI DrawText。它有两个静态方法:
TextRenderer.MeasureText
TextRenderer.DrawText
。
在 .NET 2.0 中,所有 WinForm 控件都转换为使用TextRenderer
,而不是:
(前提是您关闭关闭 UseCompatibleTextRendering
)
在 GDI+ 中绘制 Bitmap
也很慢,这就是您使用 CachedBitmap
的原因。画的很快。
CachedBitmap 对象以针对在特定设备上显示而优化的格式存储位图。要显示缓存的位图,请调用 Graphics::DrawCachedBitmap 方法。
graphics.DrawCachedBitmap(bitmap, 0, 0);
另见
MSDN: Using a Cached Bitmap to Improve Performance MSDN: CachedBitmap Class【讨论】:
这里有人:***.com/questions/71374/… 说 TextRenderer 在 Vista+ 上速度较慢。你的经验是什么?我只关心Vista/7/+ 微软人 Chris Jackson 写了一篇出色的文章,他对两者进行了基准测试:blogs.msdn.com/b/cjacks/archive/2006/05/19/… 我无法在任何 C# 库中找到 DrawCachedBitmap。因此,如果有人感兴趣,我制作了一个小型托管 C++ 包装器来使用 C# 中的 CachedBitmap (github.com/svejdo1/CachedBitmap)【参考方案2】:您查看SlimDX 了吗?它有一个围绕 Direct2D 的托管包装器,这是一个完全硬件加速的 2d API,还可以与传统 GDI 很好地混合。
编辑:
我还发现了这个你可能会感兴趣的库:SharpDX
“SharpDX 旨在用作替代托管 DirectX 框架。API 是从 DirectX SDK 标头自动生成的,具有 AnyCpu 目标,这意味着您可以在 x86 和 x64 平台上运行您的应用程序,而无需重新编译您的项目或安装程序集到 GAC 中。SharpDX 也是最快的 Managed-DirectX 实现。"
这也支持 Direct2D。
【讨论】:
我没有听说过 SlimDX 或 SharpDX。但我要提到 Direct2D。缺点是您必须从头开始创建整个控件库。 WPF 应该是硬件加速选项;但它启动缓慢、动画迟缓且难以学习。 哇 SharpDX 看起来真不错。看起来它不适用于 RDP :(【参考方案3】:Microsoft API Code Pack(2010 年 2 月存档)提供了从托管语言调用 DirectX API 的示例。
你可以得到WindowsAPICodePack-DirectX on Nuget.
【讨论】:
Direct2D 是针对应用程序的 DirectX 的高性能包装器 - 请改用它。 Microsoft 代码包也有一个使用 Direct2D 的示例。【参考方案4】:您可以尝试迁移到 WPF。 我这样做是因为 WinForms 绘制缓慢。 过渡非常困难,尤其是对于像我这样的老式编码员。
但在启动速度和 RAM 方面无法击败 WinForms。 WPF 启动缓慢,占用大量 RAM。
【讨论】:
我有使用 WPF 的经验并构建了一些 WPF 窗口。我注意到 WPF 的性能也很差,尤其是在具有低端/集成图形的机器上(例如我的工作机器)当窗口大小很大或最大化时,问题变得很严重(在 GDI+ 和 WPF 上)。 另外,我同意过渡并不容易,而且很痛苦。我仍然发现自己使用像 WinForms 这样的 WPF,即不使用花哨的绑定,而是使用大量代码来代替做很多可以自动完成的工作 - 不确定这是否会影响性能。 关于 WPF 性能的呼声越来越高(四核 nVidia 桌面的动画效果不如嵌入式 iPhone 设备?)fixwpf.org【参考方案5】:如果您的应用程序是跨平台的,我建议使用OpenTK,它是 OpenGL 的托管包装器,通常比 DirectX(托管或本机)更容易学习。 OpenTK/OpenGL 也倾向于提供比 DirectX 更好的性能。使用 OpenTK,您可以完全在 GPU 上绘制图像,然后将其光栅化为位图,该位图可以与 System.Drawing 中的 Bitmap 类互操作。
【讨论】:
以上是关于C# WinForms - 任何人都知道 C# GDI 库不是 SLOW GDI+的主要内容,如果未能解决你的问题,请参考以下文章
(C#) 从 TextBox WinForms 的删除字符中获取索引