The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

如何使用 .NET 的 QRCoder 套件產生 QRCode 圖片

QRCoder 是一套 .NET 知名的 QRCode 產生器,從 .NET Framework 的年代就存在,支援多種 QRCode 輸出格式,並且可以輸出成 BitmapPNG 等圖片類型。不過我最近發現他的最新版 v1.4.3 在 .NET 6.0 出現了一些問題,所以我在這裡紀錄一下正確的 QRCoder 使用方法。

QRCode

安裝 QRCoder 套件

無論你用 .NET Framework 或 .NET Core,都可以透過 NuGet 安裝 QRCoder 套件,它支援多目標架構,其中只有 net6.0 架構是 No dependencies. 的!

  • PMC (Package Manager Console)

    Install-Package QRCoder
    
  • .NET CLI

    dotnet add package QRCoder
    

雖然 net6.0 架構下是 No dependencies. (無相依套件) 的,但這個版本開始卻會導致有些早期常用的 QRCode 類別完全遺失,你在開發 .NET 6.0+ 的時候將會完全找不到該類別。詳細的原因可以從 Base64QRCode does not exist in 1.4.3 · Issue #361 · codebude/QRCoder 這個議題中找到。

在 .NET Framework 使用 QRCoder

在 .NET Framework 中,你可以透過幾種不同的方式產生 QRCode 圖片:

  1. 透過 QRCodeHelper 這個靜態類別提供的輔助方法來產生圖片

    var url = "https://blog.miniasp.com";
    Bitmap image = QRCodeHelper.GetQRCode(url, 10, Color.Black, Color.White, QRCodeGenerator.ECCLevel.Q);
    

    上述魔幻數字 10 是每個模組的像素大小,這個數字越大,產生的 QR Code 圖片就越大。

  2. 透過 QRCodeGenerator, QRCodeDataQRCode 這三個類別來產生圖片

    Bitmap image = null;
    
    using (QRCodeGenerator qRCodeGenerator = new QRCodeGenerator())
    {
        using (QRCodeData data = qRCodeGenerator.CreateQrCode(url, QRCodeGenerator.ECCLevel.Q))
        {
            using (QRCode qRCode = new QRCode(data))
            {
                image = qRCode.GetGraphic(10);
            }
        }
    };
    

    如果你想要變更 QRCode 圖片的顏色,可以透過 QRCode 類別的 GetGraphic() 方法來傳入 Color 結構:

    Bitmap image = null;
    
    using (QRCodeGenerator qRCodeGenerator = new QRCodeGenerator())
    {
        using (QRCodeData data = qRCodeGenerator.CreateQrCode(url, QRCodeGenerator.ECCLevel.Q))
        {
            using (QRCode qRCode = new QRCode(data))
            {
                image = qRCode.GetGraphic(10, Color.Green, Color.White, drawQuietZones: true);
            }
        }
    };
    

在 .NET 6.0+ 使用 QRCoder

由於 .NET 移除掉大多數 System.Drawing 命名空間中的類別,其中當然包含了 Bitmap 類別,也就是上述程式的 GetGraphic() 方法就無法使用了,甚至你連 QRCode 類別都找不到,如下圖示:

image

解決方法有兩種:

  1. 改用 PngByteQRCode 類別來產生圖片

    var url = "https://blog.miniasp.com";
    
    using QRCodeGenerator qRCodeGenerator = new QRCodeGenerator();
    using QRCodeData data = qRCodeGenerator.CreateQrCode(url, QRCodeGenerator.ECCLevel.Q);
    using PngByteQRCode qRCode = new PngByteQRCode(data);
    byte[] image = qRCode.GetGraphic(10);
    

    如果你想要變更 QRCode 圖片的顏色,由於 .NET 可以透過 qRCode.GetGraphic() 類別的 CreateQrCode() 方法來指定,但指定的方法跟 .NET Framework 的寫法不太一樣,你不傳入 Color 型別,反而要輸入一個 byte[] 才行,其內容則為 R, G, B 三原色的色碼:

    var url = "https://blog.miniasp.com";
    
    using QRCodeGenerator qRCodeGenerator = new QRCodeGenerator();
    using QRCodeData data = qRCodeGenerator.CreateQrCode(url, QRCodeGenerator.ECCLevel.Q);
    using PngByteQRCode qRCode = new PngByteQRCode(data);
    byte[] image = qRCode.GetGraphic(10,
                      darkColorRgba: new byte[] { 0, 90, 0 }, // RGB
                      lightColorRgba: new byte[] { 255, 255, 255 }); // RGB
    
  2. 改用 PngByteQRCodeHelper 這個靜態類別提供的輔助方法來產生圖片

    這邊與 .NET Framework 的用法最主要的差異,就是 PngByteQRCodeHelper 類別的 GetQRCode() 方法,回傳的型別是 byte[],而不是 Bitmap

    var url = "https://blog.miniasp.com";
    byte[] image = PngByteQRCodeHelper.GetQRCode(url, QRCodeGenerator.ECCLevel.Q, 10);
    

什麼是 ECCLevel

ECC Level 是 Error Correction Code Level 的縮寫,中文意思是「錯誤更正等級」,這個等級越高,可以容許的錯誤越多!

這個容錯更正等級代表著 QR Code 圖片當有破損或變形時,QR Code 閱讀器可以容錯的程度,從 L (Lowest) 到 H (Highest) 共分成 4 種等級:

  1. ECC Level L: 此等級可以忍受 QR Code 圖片有最多 7% 的破損或變形 ( L = Lowest )
  2. ECC Level M: 此等級可以忍受 QR Code 圖片有最多 15% 的破損或變形 ( M = Medium )
  3. ECC Level Q: 此等級可以忍受 QR Code 圖片有最多 25% 的破損或變形 ( Q = Quarter )
  4. ECC Level H: 此等級可以忍受 QR Code 圖片有最多 30% 的破損或變形 ( H = Highest )

一般而言,大多數人都會選擇 Q 這個容錯等級,因為他可以容許 25% (1/4) 的錯誤,而且圖片大小也不會太大。

產生文字格式的 QRCode 圖片

如果你想在 Console 模式下輸出一份 QRCode,那就可以使用 AsciiQRCodeHelper 這個靜態類別提供的 GetQRCode() 輔助方法來產生文字格式的圖片,他的用法跟 PngByteQRCodeHelper 類似,只是他的回傳型別是 string 而已:

string txt = AsciiQRCodeHelper.GetQRCode(url,
    pixelsPerModule: 1,
    darkColorString: "██",
    whiteSpaceString: "  ",
    eccLevel: QRCodeGenerator.ECCLevel.Q);
Console.WriteLine(txt);

這裡的 darkColorString 參數,要放入兩個 U+2588 字元 (全滿的方塊),而 whiteSpaceString 參數,則是放入兩個空白字元,輸出顯示的時候要注意字型要選用等寬字體。

相關連結

留言評論