1. 程式人生 > 其它 >.NET Core 專案Linux環境下生成二維碼

.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;
}