在当前所有渲染框架里面,做 2D 渲染的,最好的框架是 Win2d 这个提供了大量底层接口封装,不仅性能高同时接口设计非常好
在很久之前,只有在 UWP 等现代应用才能使用 Win2d 而 WPF 是不能使用的。好在微软开放了一些黑科技,可以在 WPF 上使用 Win2d 渲染,下面就让我告诉大家如何在 WPF 上使用
在 2019年7月03日 这个技术还是属于黑科技,还没有正式发布,在开始使用之前,有一定的环境要求
- 需要 VisualStudio 2017 和以上,点击Visual Studio下载链接下载最新的工具
- 需要在 VisualStudio 的开发添加 UWP 和桌面开发
- 需要在设备安装 .NET Framework 4.7.2 及以上,同时新建项目需要选择 .NET Framework 4.7.2 和以上。有小伙伴说 45 也是可以的,但是步骤会更多,建议小伙伴在看完本文测试过了才尝试降级
- 开发和运行设备是 Windows 10 版本 1903 和以上
- 开发设备上安装 UWP 的 SDK 版本是 18362 及以上 Windows 10 SDK - Windows 应用开发
新建一个 WPF 的 .NET Framework 4.8 项目,在这个项目上面安装下面 NuGet 包
- Microsoft.Windows.SDK.Contracts
- Microsoft.VCRTForwarders.140
- System.Numerics.Vectors
- Win2D.uwp
如果有安装不上的,例如有下面提示
右击编辑 csproj 文件,在 csproj 文件里面添加下面代码。注意此时你新建的项目使用的 nuget 格式需要新的 Nuget 格式,也就是不带 package.config 文件的格式
这样就可以强制安装
准备好了环境和 NuGet 之后就可以开始开发了
和之前博客 WPF 使用 Composition API 做高性能渲染 所说方法搭建代码
搭建出 CompositionHost 和 CompositionHostControl 两个类,然后在 CompositionHostControl 里面添加 Win2d 相关方法
在 CompositionHostControl 的构造函数给 Win2d 初始化
以上忽略代码可以在 Windows.UI.Composition-Win32-Samples 找到
在 CompositionHostControl_Loaded
事件里面才是核心代码
想要让 Win2d 绘制在界面上,需要在界面存放一张平面,让 Win2d 在这个平面上绘制,然后将平面加入到渲染的平面列表里面,这样就可以进行渲染了
在 LoadSurface 方法里面进行绘制,请看创建代码
这样就可以将 Win2d 的内容渲染到一个平面上,然后将这个平面作为画刷,在微软的代码里面是将这个画刷作为亚克力的画刷,然后将亚克力放在内容里面
下面是简化的代码
现在就完成了在 WPF 里面使用 Win2d 顺便还提供了亚克力的功能
其实本文主要不是告诉大家如何写代码,而是如何让官方的代码可以运行
在运行过程可能会遇到以下的坑
如在开始编译的时候提示下面代码
主要原因是现在 Microsoft.Windows.SDK.Contracts 只能让 Win2d 的 1.22 版本运行,解决方案是将原本的 1.23 版本降级到 1.22 版本
在运行过程,运行到 _canvasDevice = CanvasDevice.GetSharedDevice()
的时候提示下面的代码
这个问题是因为没有在 app.manifest 文件里面添加下面代码
或者这个文件没有在 csproj 声明,也就是没有在项目文件找到下面代码
在运行的时候,还是在 _canvasDevice = CanvasDevice.GetSharedDevice()
提示下面的代码
这个问题是在输出文件夹缺少文件,请确定当前使用的是 x64 的设备,同时进行 AnyCpu 编译,没有勾选首选 32 的程序
然后确定在 bin\debug
文件夹里面是否存在以下文件
- vcruntime140_app.dll
- msvcp140_app.dll
- Microsoft.Graphics.Canvas.dll
- System.Numerics.Vectors.dll
- Microsoft.Graphics.Canvas.winmd
在安装 Microsoft.VCRTForwarders.140
默认就会创建前面两个文件,在进行x64编译的时候。如果使用的是 AnyCpu 编译,那么就需要手动拷贝文件
而 Microsoft.Graphics.Canvas.dll 文件是需要手动拷贝的
手动复制文件的方法是打开自己的本地 .nuget 源,在 c:\Users\用户名\.nuget\packages\
里面可以找到
如我的 Microsoft.VCRTForwarders.140 内容在 c:\Users\lindexi.github.io\.nuget\packages\microsoft.vcrtforwarders.140\1.0.0-rc\runtimes\win10-x64\native\release\
文件,将里面的文件复制到输出文件夹
打开 c:\Users\lindexi.github.io\.nuget\packages\win2d.uwp\1.22.0\runtimes\win10-x64\native\
将 Microsoft.Graphics.Canvas.dll 文件复制到输出文件夹
请将上面文件夹的用户名替换为你自己的用户名
当然这样的呆魔大家一定不想使用,于是我将需要添加的文件放在项目文件,设置自动输出,请小伙伴换我的项目试试
我将代码放在 Github 只需要下载代码,然后打开 sln 文件,右击还原项目,然后在 AnyCpu 下按下运行就可以
原文链接: http://blog.lindexi.com/post/WPF-%E4%BD%BF%E7%94%A8-Win2d-%E6%B8%B2%E6%9F%93
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。
欢迎转载、使用、重新发布,但务必保留文章署名 林德熙 (包含链接: https://blog.lindexi.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我 联系。