用ZXing.Net生成二维码需三步:1.安装ZXing.Net(非ZXing),2.用BarcodeWriter配置EncodingOptions(宽高、UTF-8编码、容错等级),3.调用Write生成Bitmap并用using妥善释放;Web场景应写入MemoryStream返回,避免文件I/O与GDI+异常。
用 ZXing.Net 生成二维码图片,核心就三步
直接上手最稳的方式是用 zxing.net(不是 java 版 zxing),它原生支持 .net,能直接输出 bitmap 或 stream,不用额外转码。别下错包——nuget 上搜 zxing.net,不是 zxing(那个是 java 移植版,缺图像导出)。
常见错误现象:调用 Write 方法后返回 null,或图片全是黑块。基本都是没设好 EncodingOptions 或传了空/非法字符串。
- 必须指定
Width和Height,不设默认是 100×100,小字扫码容易失败 -
CharacterSet设成"UTF-8",否则中文变问号 - 输入内容不能为
null或全空白,string.IsNullOrWhiteSpace()建议提前校验 - 推荐用
BarcodeWriter而非底层MultiFormatWriter,省去手动转BitMatrix
var writer = new BarcodeWriter
{
Format = BarcodeFormat.QR_CODE,
Options = new EncodingOptions
{
Width = 300,
Height = 300,
CharacterSet = "UTF-8"
}
};
var bitmap = writer.Write("https://example.com"); // 返回 Bitmap,可直接 Save()
Bitmap 保存为 PNG/JPG 时注意 GDI+ 锁定和内存泄漏
Bitmap.Save() 看似简单,但 C# 中如果没正确释放资源,下次再生成同一路径文件会抛 "A generic error occurred in GDI+"。这不是 ZXing 的问题,是 .NET 图形资源没关干净。
- 务必用
using包裹Bitmap,哪怕只用一次 - 不要用
Image.Save()直接存,Bitmap才保证像素级控制 - 存 PNG 推荐用
ImageFormat.Png;JPG 压缩质量建议显式设EncoderParameter,否则默认质量低、边缘模糊 - 路径含中文或特殊字符?先用
Path.GetInvalidFileNameChars()过滤,别等IOException才发现
using (var bitmap = writer.Write("text"))
{
bitmap.Save(@"C:\qrcode.png", ImageFormat.Png);
}
在 ASP.NET Core API 里返回二维码,别直接写文件
Web 场景下,用户要的是即时响应,不是服务器磁盘上多一个文件。直接 Save() 到磁盘再读取返回,既慢又容易并发冲突(比如同名覆盖或文件锁)。应该走内存流。
- 用
MemoryStream接住Bitmap.Save()输出,再设Content-Type: image/png - 别忘了
stream.Position = 0,否则返回空内容 - 如果接口要支持格式切换(PNG/JPG),根据 query 参数动态选
ImageFormat,别硬编码 - 大并发下注意
Bitmap构造开销,可考虑缓存常用尺寸的EncodingOptions实例
using var ms = new MemoryStream(); bitmap.Save(ms, ImageFormat.Png); ms.Position = 0; return File(ms, "image/png");
中文乱码、扫码失败,大概率是编码或容错等级没调对
ZXing 默认容错等级是 L(约 7% 恢复能力),短文本够用,但带中文、URL 或需要抗污损时,得手动提级。另外,CharacterSet 不等于系统编码——即使项目是 UTF-8,ZXing 也得明确告诉它“按 UTF-8 编”。
- 容错等级选
M(15%)或Q(25%),用Hint设置:options.Hints.Add(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M) -
CharacterSet必须显式设为"UTF-8",不设或设错(如"GB2312")会导致扫描器解码失败 - 超长 URL 或含特殊符号(如
&、=)?先Uri.EscapeDataString()再喂给 ZXing - 测试时别只用手机微信扫——微信对低容错/小尺寸容忍高,但工业扫码枪可能直接拒识
复杂点在于:容错越高,二维码模块越密,小尺寸下反而更难扫;而尺寸放大又影响页面布局。没有银弹,得按实际使用设备和距离做权衡。











