.NET Core使用SkiaSharp快速生成二维码( 真正跨平台方案)

发布时间:2024年01月18日

前言

在.NET 6之前我们一直是使用QRCoder来生成二维码(QRCoder是一个非常强大的生成二维码的组件,用到了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()

报错原因

由于 System.Drawing.Common 被设计为 Windows 技术的精简包装器,因此其跨平台实现欠佳。

libgdiplus?是本机端?System.Drawing.Common?跨平台实现的主要提供程序。libgdiplus?实际上是对?System.Drawing.Common?所依赖的 Windows 部分的重新实现。该实现使?libgdiplus?成为一个重要的组件。它大约有 30,000 行 C 代码,大部分未经测试,而且缺少很多功能。libgdiplus?还具有许多用于图像处理和文本呈现的外部依赖项,例如 cairo、pango 和其他本机库。这些依赖项使得维护和交付组件更具挑战性。自从包含 Mono 跨平台实现以来,我们已将许多从未得到修复的问题重定向到?libgdiplus。相比之下,我们采用的其他外部依赖项,例如 icu 或 openssl,都是高质量的库。使?libgdiplus?的功能集和质量与 .NET 堆栈的其余部分相媲美是不可行的。

官方建议

在非 Windows 环境中,推荐使用 SkiaSharp 和 ImageSharp 等库来完成跨平台的图像处理操作。这些库提供了更全面和稳定的功能支持,适用于大多数图形操作需求。而 System.Drawing.Common 将主要继续在 Windows 窗体和 GDI+ 的上下文中进行演化。

SkiaSharp介绍

SkiaSharp是由Mono团队维护的开源项目,它是基于Google的Skia图形库的.NET跨平台绑定,提供了强大的2D图形绘制和处理功能,适用于多个平台,包括Windows、macOS、Linux、iOS和Android,可用于创建高性能的、可移植的2D图形应用程序。

SkiaSharp 提供了跨平台绑定,适用于以下平台:

  • .NET Standard 1.3

  • .NET Core

  • .NET 6

  • Tizen

  • Android

  • iOS

  • tvOS

  • macOS

  • Mac Catalyst

  • WinUI 3 (Windows App SDK / Uno Platform)

  • Windows Classic Desktop (Windows.Forms / WPF)

  • Web Assembly (WASM)

  • Uno Platform (iOS / macOS / Android / WebAssembly)

这些平台可以使用 SkiaSharp 来进行跨平台的图形渲染和绘制操作。

使用SkiaSharp快速生成二维码

1、安装SkiaSharp.QrCode库

使用SkiaSharp生成二维码的QR码生成器(无需使用System.Drawing)。

图片

2、生成二维码图片

????????///?<summary>
????????///?生成二维码图片
????????///?</summary>
????????public?static?void?GenerateQRCode()
????????{
????????????var?qrCodeContent?=?"追逐时光者";
????????????using?(var?generator?=?new?QRCodeGenerator())
????????????{
????????????????//?创建二维码(并设置纠错能力最高级)
????????????????var?createQrCode?=?generator.CreateQrCode(qrCodeContent,?ECCLevel.H);

????????????????var?skImageInfo?=?new?SKImageInfo(300,?300);

????????????????//?创建SkiaSharp画布
????????????????using?(var?surface?=?SKSurface.Create(skImageInfo))
????????????????{
????????????????????var?canvas?=?surface.Canvas;

????????????????????//?渲染二维码到画布
????????????????????canvas.Render(createQrCode,?skImageInfo.Width,?skImageInfo.Height);

????????????????????using?(var?image?=?surface.Snapshot())//?获取画布快照
????????????????????using?(var?data?=?image.Encode(SKEncodedImageFormat.Png,?100))//?编码画布快照为PNG格式的数据
????????????????????using?(var?stream?=?File.OpenWrite(@"MyQRCode.png"))
????????????????????{
????????????????????????data.SaveTo(stream);//?将数据保存到文件流中,生成二维码图片
????????????????????}
????????????????}
????????????}
????????}
二维码的纠错能力通常分为四个级别
  • 在生成二维码时,纠错能力(Error Correction Capability)指的是QR码中包含的冗余信息,用于修复可能出现的损坏或错误。QR码可以通过添加冗余信息来提高其容错性,即使在一定程度上受到损坏或噪声的干扰,仍然可以正确地解码和还原二维码的内容。

  • QR码的纠错能力通常分为四个级别,从低到高依次为:L、M、Q、H。其中,纠错能力最低的级别为L,最高的级别为H。纠错能力越高,二维码中包含的冗余信息就越多,因此可以更好地恢复丢失或损坏的数据。

namespace?SkiaSharp.QrCode
{
????public?enum?ECCLevel
????{
????????L,
????????M,
????????Q,
????????H
????}
}

参考文章

  • https://learn.microsoft.com/zh-cn/dotnet/core/compatibility/core-libraries/6.0/system-drawing-common-windows-only

  • QRCoder:https://github.com/codebude/QRCoder

项目源码地址

更多实用功能特性欢迎前往开源地址查看👀,别忘了给项目一个Star💖。

https://github.com/mono/SkiaSharp

https://github.com/guitarrapc/SkiaSharp.QrCode

优秀项目和框架精选

该项目已收录到C#/.NET/.NET Core优秀项目和框架精选中,关注优秀项目和框架精选能让你及时了解C#、.NET和.NET Core领域的最新动态和最佳实践,提高开发效率和质量。坑已挖,欢迎大家踊跃提交PR,自荐(让优秀的项目和框架不被埋没🤞)。

https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md

文章来源:https://blog.csdn.net/qq_37237487/article/details/135671979
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。