.NET Core 项目Linux环境下生成二维码

问题:

公司系统开发中,需要对企微授权链接进行二维码生成,然后向客户提供;当然,首当其冲想到的是使用ZXing.NET库进行实现,毕竟生成简单二维码也就那几句代码;
然而,在本地环境中,一切都很正常,但是进入到开发环境中却出现了如下的异常:

System.TypeInitializationException: The type initializer for'Gdip' threw an exception.


代码:

/// <summary>
/// 生成二维码
/// </summary>
/// <param name="value">value</param>
/// <param name="width">二维码宽,默认500</param>
/// <param name="height">二维码高,默认500</param>
public static Bitmap ToQrCode(this string value, int width = 500, int height = 500)
{
    BarcodeWriter writer = new BarcodeWriter();
    writer.Format = BarcodeFormat.QR_CODE;
    QrCodeEncodingOptions options = new QrCodeEncodingOptions
    {
        DisableECI = true,
        CharacterSet = "UTF-8",
        Margin = 1,
        Width = width,
        Height = height
    };
    writer.Options = options;

    return writer.Write(value);
}

原因:

从异常信息中不难看出来,是 System.Drawing 接口抛出的异常;
经过冲浪发现,System.Drawing.Common被归为Windows特定的库,是对windows下绘图的一个简单封装,缺少跨平台的支持,这也就导致了我在本地环境(windows)下正常,但是去到了开发环境(Linux)却发生了异常;

解决:

1、在linux环境下安装libgdipplus包
libgdiplus 实际上是对 System.Drawing.Common 所依赖的 Windows 部分针对linux平台下的重新实现;

2、更换图像库
如使用如下库:

在我司,架构师说不推荐使用第一种方式,毕竟迁移项目或者增加节点时需要进行相应的服务器配置,这是相对比较麻烦的;
所以我们选择了第二种,且使用了SixLabors.ImageSharp进行了图片的处理;同时,生成二维码的库也换成了针对SixLabors.ImageSharp实现的ZXing.NET 版本的库;
对此需要安装如下包:

  • ZXing.Net.Bindings.ImageSharp.V2
  • SixLabors.ImageSharp

具体实现代码如下:

using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.PixelFormats;
using System.IO;
using ZXing;

/// <summary>
/// 生成二维码
/// </summary>
/// <param name="value">value</param>
/// <param name="width">二维码宽,默认500</param>
/// <param name="height">二维码高,默认500</param>
public static Bitmap ToQrCode(this string value, int width = 500, int height = 500)
{
    var writer = new ZXing.ImageSharp.BarcodeWriter<Rgba32>
    {
        Format = BarcodeFormat.QR_CODE,
        Options = new ZXing.QrCode.QrCodeEncodingOptions
        {
            DisableECI = true,
            CharacterSet = "UTF-8",
            Width = width,
            Margin = 1
        }
    };
    var image = writer.WriteAsImageSharp<Rgba32>(value);
    var ms = new MemoryStream();
    image.Save(ms, new PngEncoder());
    return ms;
}
posted @ 2022-03-21 10:37  Memoyu  阅读(1139)  评论(5编辑  收藏  举报