ZXing.Net生成二维码需显式配置EncodingOptions:设Width/Height(如300)、Margin=2、CharacterSet="UTF-8"、ErrorCorrection=M;Code128仅支持数字/大写字母,中文或小写需换QR_CODE;Bitmap用后立即Dispose;ASP.NET Core返回图片应流式处理而非ToArray。

用 ZXing.Net 生成二维码:别漏掉 EncodingOptions
ZXing.Net 默认生成的二维码可能太小、容错低或不支持中文。直接调用 BarcodeWriter.Write() 得到的图经常扫不出来,问题往往出在没配置编码参数。
关键点是必须显式传入 EncodingOptions,否则默认使用最低容错(L级)、无空白边距、尺寸按内容自动缩放——这在实际场景中基本不可用。
-
Width和Height必须设为具体像素值(如 300),不能依赖默认行为 -
ErrorCorrection推荐设为ZXing.QrCode.Internal.ErrorCorrectionLevel.M(中等容错) - 中文内容务必加
CharacterSet = "UTF-8",否则乱码 - 建议设置
Margin = 2(最小边距,单位像素),避免扫码器裁切失败
var writer = new ZXing.BarcodeWriter
{
Format = ZXing.BarcodeFormat.QR_CODE,
Options = new ZXing.Common.EncodingOptions
{
Width = 300,
Height = 300,
Margin = 2,
CharacterSet = "UTF-8",
ErrorCorrection = ZXing.QrCode.Internal.ErrorCorrectionLevel.M
}
};
var bitmap = writer.Write("https://example.com");
生成 Code128 条形码:注意输入字符串合法性
Code128 不是“什么都能扫”的万能格式。ZXing.Net 对输入字符有严格要求:纯数字、大写字母、控制符(如 GS)可直接编码;但小写字母、中文、空格、特殊符号会触发 ArgumentException 或生成无效码。
常见错误现象:System.ArgumentException: Input string is not valid Code 128 data。这不是库 bug,是规范限制。
- 若原始数据含小写,先转大写(
input.ToUpper())再传入 - 含中文或 Unicode 字符?改用
BarcodeFormat.PDF_417或QR_CODE,Code128 原生不支持 - 空格和连字符(
-、.)通常合法,但开头/结尾的空格会被忽略,建议Trim() - 长度超过 48 字符时,部分扫描枪识别率下降,建议前端做长度截断或换格式
Bitmap 输出后立刻释放资源:避免 GDI+ 异常
用 BarcodeWriter.Write() 返回的 Bitmap 直接保存或转 Base64 时,如果没手动调用 Dispose(),后续图像操作(如缩放、叠加文字)可能抛出 System.Runtime.InteropServices.ExternalException: A generic error occurred in GDI+。
这不是 ZXing 的问题,而是 .NET 中 Bitmap 持有 GDI 句柄,未释放就跨线程/跨作用域访问会冲突。
- 务必在使用完后立即
bitmap.Dispose(),不要依赖 GC - 若需多次复用图像(如加 logo、打水印),先用
new Bitmap(bitmap)克隆一份再操作原图 - ASP.NET Core 中返回
FileStreamResult时,别在 Action 内直接Dispose(),应交给框架流管理
ASP.NET Core 中返回二维码图片:别用 MemoryStream.ToArray()
有人习惯把生成的 Bitmap 用 ToArray() 转成字节数组再封装成 FileContentResult,这会导致内存暴涨——特别是高并发下,每个请求都拷贝一次完整位图数据。
更稳妥的做法是用 MemoryStream 流式写入并重置位置,让框架直接读取流。
using var ms = new MemoryStream(); bitmap.Save(ms, ImageFormat.Png); ms.Position = 0; return File(ms, "image/png"); // 不要 ms.ToArray()
真正容易被忽略的是:ZXing.Net 默认输出的是 32 位 ARGB 位图,PNG 保存时若未指定编码器参数,可能带透明通道,某些老旧扫码设备不兼容。如遇扫码失败,可强制转为 24 位 RGB:bitmap.Clone(new Rectangle(0, 0, bitmap.Width, bitmap.Height), PixelFormat.Format24bppRgb)。


















