ThoughtWorks.QRCode 是經典的 .NET QR Code 庫,雖已停止更新,但 API 簡單、無外部依賴、支援 .NET Framework 2.0+,適合快速在舊專案整合 QR Code 功能。新專案建議考慮 QRCoder(純 C#、支援 .NET Core/Standard、功能更豐富)。
ThoughtWorks.QRCode.dll(或 NuGet:Install-Package ThoughtWorks.QRCode)。using ThoughtWorks.QRCode.Codec;
using ThoughtWorks.QRCode.Codec.Data;
using ThoughtWorks.QRCode.Codec.Util;
public Image GenerateQrCode(string data,
QRCodeEncoder.ENCODE_MODE encodeMode = QRCodeEncoder.ENCODE_MODE.BYTE,
int scale = 4, // 模組大小(像素),建議 3-8
int version = 0, // 版本 1-40,0 表自動
QRCodeEncoder.ERROR_CORRECTION errorCorrection = QRCodeEncoder.ERROR_CORRECTION.M)
{
var encoder = new QRCodeEncoder
{
QRCodeEncodeMode = encodeMode,
QRCodeScale = scale,
QRCodeVersion = version,
QRCodeErrorCorrect = errorCorrection
};
// 編碼模式說明:
// NUMERIC : 僅數字 0-9,最緊湊
// ALPHA_NUMERIC: 數字 + 大寫字母 + 空格 $ % * + - . / :
// BYTE : ISO-8859-1 位元組(預設,支援中文需注意編碼)
// KANJI : 日文漢字
return encoder.Encode(data);
}
private void btnGenerate_Click(object sender, EventArgs e)
{
try
{
var encoder = new QRCodeEncoder();
// 1. 編碼模式
switch (cboEncoding.SelectedItem?.ToString())
{
case "Byte": encoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE; break;
case "AlphaNumeric": encoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.ALPHA_NUMERIC; break;
case "Numeric": encoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.NUMERIC; break;
}
// 2. 尺寸
if (int.TryParse(txtSize.Text, out int scale)) encoder.QRCodeScale = scale;
// 3. 版本
if (int.TryParse(cboVersion.Text, out int version)) encoder.QRCodeVersion = version;
// 4. 錯誤修正等級
switch (cboCorrection.SelectedItem?.ToString())
{
case "L": encoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.L; break; // 7%
case "M": encoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M; break; // 15%
case "Q": encoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.Q; break; // 25%
case "H": encoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.H; break; // 30%
}
string data = txtData.Text;
Image qrImage = encoder.Encode(data);
picPreview.Image = qrImage;
// 可選:儲存檔案
// qrImage.Save("qrcode.png", ImageFormat.Png);
}
catch (Exception ex)
{
MessageBox.Show($"生成失敗:{ex.Message}");
}
}
public string DecodeQrCode(Image qrImage)
{
var decoder = new QRCodeDecoder();
// QRCodeBitmapImage 為 ThoughtWorks 封裝的 Bitmap 適配器
string decoded = decoder.Decode(new QRCodeBitmapImage(new Bitmap(qrImage)));
return decoded;
}
// 使用範例
private void btnDecode_Click(object sender, EventArgs e)
{
if (picPreview.Image == null) return;
try
{
string result = DecodeQrCode(picPreview.Image);
txtData.Text = result;
}
catch (Exception ex)
{
MessageBox.Show($"解析失敗:{ex.Message}");
}
}
// QrCodeHandler.ashx.cs
public class QrCodeHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
string data = context.Request.QueryString["data"] ?? "https://example.com";
int scale = int.TryParse(context.Request.QueryString["scale"], out var s) ? s : 4;
string level = context.Request.QueryString["level"] ?? "M";
var encoder = new QRCodeEncoder
{
QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE,
QRCodeScale = scale,
QRCodeErrorCorrect = ParseErrorLevel(level)
};
using (Image img = encoder.Encode(data))
{
context.Response.ContentType = "image/png";
img.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Png);
}
}
private QRCodeEncoder.ERROR_CORRECTION ParseErrorLevel(string level)
{
switch (level.ToUpper())
{
case "L": return QRCodeEncoder.ERROR_CORRECTION.L;
case "Q": return QRCodeEncoder.ERROR_CORRECTION.Q;
case "H": return QRCodeEncoder.ERROR_CORRECTION.H;
default: return QRCodeEncoder.ERROR_CORRECTION.M;
}
}
public bool IsReusable => false;
}
前端使用:<img src="QrCodeHandler.ashx?data=Hello%20World&scale=5&level=H" />
[HttpPost]
public ActionResult DecodeUpload(HttpPostedFileBase file)
{
if (file == null || file.ContentLength == 0) return Json(new { success = false, msg = "請選擇圖片" });
try
{
using (var stream = file.InputStream)
using (var bitmap = new Bitmap(stream))
{
var decoder = new QRCodeDecoder();
string result = decoder.Decode(new QRCodeBitmapImage(bitmap));
return Json(new { success = true, data = result });
}
}
catch (Exception ex)
{
return Json(new { success = false, msg = ex.Message });
}
}
| 問題 | 解決方案 |
|---|---|
| 中文內容掃描亂碼 | 1. 確保編碼模式為 BYTE。2. 生成前將字串轉 UTF-8 位元組:encoder.Encode(Encoding.UTF8.GetBytes(data))(需庫支援)。3. 掃描端設定 UTF-8 解碼。 |
| 圖片太小無法辨識 | 增加 QRCodeScale(建議 ≥4),確保模組 ≥4px;列印建議 ≥8px。 |
| 錯誤修正等級選擇 | L(7%) 空間最小、M(15%) 平衡、Q(25%) 較強、H(30%) 最強。有 Logo/圖案覆蓋時必須用 H。 |
| 版本號設定 | 0=自動。手動指定時需確保資料容量足夠,否則拋出異常。 |
| 效能問題 | 大量生成時重用 QRCodeEncoder 實例;避免頻繁建立 Bitmap 物件。 |
// NuGet: Install-Package QRCoder
using QRCoder;
public Image GenerateWithQRCoder(string data)
{
var generator = new QRCodeGenerator();
var qrCodeData = generator.CreateQrCode(data, QRCodeGenerator.ECCLevel.Q);
var qrCode = new QRCode(qrCodeData);
// 內建支援 PNG、SVG、ASCII Art、Bitmap
return qrCode.GetGraphic(20); // pixels per module
}
QRCoder 優勢:.NET Standard 2.0、無 System.Drawing 依賴(可在 Linux Docker 運行)、支援 Logo 嵌入、多種輸出格式、活躍維護中。
ThoughtWorks.QRCode 以簡單 API 快速實現 QR Code 生成與解析,適合維護舊式 ASP.NET 專案。核心類別為 QRCodeEncoder(生成)與 QRCodeDecoder(解析),關鍵參數包含編碼模式、尺寸、版本、錯誤修正等級。實務上需注意中文編碼、圖片尺寸、錯誤修正等級選擇。新專案強烈建議遷移至 QRCoder,獲得跨平台支援、更豐富功能與持續更新。