|
之前在使用 .NET Framework 开发 ASP.NET 项目的时候,都是部署在 Windows 系统,还无法跨平台,可以使用 System.Drawing 来生成图片验证码,参考如下:
在线使用 .NET Core 项目开发,生成图片验证码需要引用 System.Drawing.Common 类库,但是现在 System.Drawing.Common NuGet 包现在被归为 Windows 特定的库。 在为非 Windows 操作系统编译时,平台分析器会在编译时发出警告。如下图所示:
可在所有平台上访问此调用站点。"Font" 仅在 'windows' 上受支持。
在 .NET 6 之前,使用 System.Drawing.Common 包不会产生任何编译时警告,也不会引发任何运行时异常。从 .NET 6 开始,当为非 Windows 操作系统编译引用代码时,平台分析器会发出编译时警告。 此外,除非设置了配置选项,否则将引发以下运行时异常:
System.TypeInitializationException : The type initializer for 'Gdip' threw an exception.
---- System.PlatformNotSupportedException : System.Drawing.Common is not supported on non-Windows platforms. See https://aka.ms/systemdrawingnonwindows for more information.
Stack Trace:
at System.Drawing.SafeNativeMethods.Gdip.GdipCreateBitmapFromFile(String filename, IntPtr& bitmap)
/_/src/libraries/System.Drawing.Common/src/System/Drawing/Bitmap.cs(42,0): at System.Drawing.Bitmap..ctor(String filename, Boolean useIcm)
/_/src/libraries/System.Drawing.Common/src/System/Drawing/Bitmap.cs(25,0): at System.Drawing.Bitmap..ctor(String filename)
/_/src/libraries/System.Resources.ResourceManager/tests/ResourceManagerTests.cs(270,0): at System.Resources.Tests.ResourceManagerTests.EnglishImageResourceData()+MoveNext()
/_/src/libraries/System.Linq/src/System/Linq/Select.cs(136,0): at System.Linq.Enumerable.SelectEnumerableIterator`2.MoveNext()
----- Inner Stack Trace -----
/_/src/libraries/System.Drawing.Common/src/System/Drawing/LibraryResolver.cs(31,0): at System.Drawing.LibraryResolver.EnsureRegistered()
/_/src/libraries/System.Drawing.Common/src/System/Drawing/GdiplusNative.Unix.cs(65,0): at System.Drawing.SafeNativeMethods.Gdip.PlatformInitialize()
/_/src/libraries/System.Drawing.Common/src/System/Drawing/Gdiplus.cs(27,0): at System.Drawing.SafeNativeMethods.Gdip..cctor()
错误参考:
在跨平台对图像处理,微软官方文档建议使用如下类库:
- ImageSharp
- SkiaSharp
- Microsoft.Maui.Graphics
参考:https://docs.microsoft.com/zh-cn/dotnet/core/compatibility/core-libraries/6.0/system-drawing-common-windows-only
本文使用 SkiaSharp 类库来生成图形验证码,SkiaSharp 是基于 Google 的 Skia 图形库 ( skia.org ) 的用于 .NET 平台的跨平台 2D 图形 API。它提供了一个全面的 2D API,可以跨移动、服务器和桌面模型使用来渲染图像。
地址:https://github.com/mono/SkiaSharp
首先,新建 ASP.NET Core 6 的项目,引用 SkiaSharp 相关类库,如下:
注意,如果项目需要部署到 Linux 系统,需要引用 SkiaSharp.NativeAssets.Linux 类库,否则会报错如下:
4月 03 18:51:06 raspberrypi dotnet[6203]: fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]
4月 03 18:51:06 raspberrypi dotnet[6203]: An unhandled exception has occurred while executing the request.
4月 03 18:51:06 raspberrypi dotnet[6203]: System.TypeInitializationException: The type initializer for 'SkiaSharp.SKImageInfo' threw an exception.
4月 03 18:51:06 raspberrypi dotnet[6203]: ---> System.DllNotFoundException: Unable to load shared library 'libSkiaSharp' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: liblibSkiaSharp: cannot open shared object file: No such file or directory
4月 03 18:51:06 raspberrypi dotnet[6203]: at SkiaSharp.SkiaApi.sk_colortype_get_default_8888()
4月 03 18:51:06 raspberrypi dotnet[6203]: at SkiaSharp.SKImageInfo..cctor()
4月 03 18:51:06 raspberrypi dotnet[6203]: --- End of inner exception stack trace ---
4月 03 18:51:06 raspberrypi dotnet[6203]: at HomeCloud.ImageCaptcha.GetCaptcha(String captchaText, Int32 width, Int32 height, Int32 lineNum, Int32 lineStrookeWidth) in C:\Users\itsvse_pc\source\repos\ConsoleApp1\HomeCloud\ImageCaptcha.cs:line 184
4月 03 18:51:06 raspberrypi dotnet[6203]: at HomeCloud.Controllers.HomeController.Test() in C:\Users\itsvse_pc\source\repos\ConsoleApp1\HomeCloud\Controllers\HomeController.cs:line 80
4月 03 18:51:06 raspberrypi dotnet[6203]: at lambda_method34(Closure , Object , Object[] )
为了考虑到不同系统下可能会缺少一些 font 字体,导致无法正常显示验证码的信息,我们需要手动将字体复制到项目中,在项目新建 fonts 文件夹,将字体复制进去,如下图:
配置如下:
根据网上的参考资料,测试生成的图形验证码如下:
生成的验证码有两个缺点:验证码全是黑色(容易被 OCR 识别),验证码字母之间没有间隔都挤在一起,为了解决这两个问题,我优化了一下代码,如下:
HomeController 控制器代码如下:
最终效果图如下:
最后,附上字体文件:
(完)
|
上一篇:【转】.NET 6 新特性 Enumerable.Chunk()下一篇:Angular 阻止父类点击事件的触发
|