ZXing.Net生成二维码需显式设置Format和EncodingOptions(含Width、Height、CharacterSet),否则报空引用异常;QRCoder需用QRCodeData再生成图像;识别时BitmapLuminanceSource对图像质量敏感,须确保清晰、高对比、正向。

用 ZXing.Net 生成二维码:别直接 new BarcodeWriter 就跑
默认构造的 BarcodeWriter 不带编码器,直接写入会抛 NullReferenceException。必须显式指定 Format 和 Options,否则生成的图是空的或报错。
-
Options至少要设Width、Height,否则输出尺寸为 0 × 0 - 中文内容必须设
EncodingOptions.CharacterSet = "UTF-8",否则乱码 - 推荐用
BarcodeWriter<bitmap></bitmap>而非泛型默认类型,避免隐式转换失败
var writer = new BarcodeWriter<Bitmap>
{
Format = BarcodeFormat.QR_CODE,
Options = new EncodingOptions
{
Width = 300,
Height = 300,
Margin = 1,
CharacterSet = "UTF-8"
}
};
var bitmap = writer.Write("https://example.com"); // 返回 Bitmap,可直接 Save
QRCoder 生成二维码:注意 QRCodeData 是中间态,不是图片
很多人调完 QRCodeGenerator.CreateQrCode() 就以为完事了,其实返回的是 QRCodeData,得再喂给 QRCode 才能出图。漏这步会得到空对象或编译不报错但运行无图。
-
QRCodeData只存点阵逻辑(bool[][]),不含像素、颜色、尺寸信息 -
QRCode.GetGraphic()才真正生成Bitmap;传参控制模块大小、前景/背景色、图标嵌入等 - 嵌入 logo 时,
iconSizePercent建议 ≤ 15,否则纠错能力骤降,扫码失败率明显升高
var gen = new QRCodeGenerator();
var data = gen.CreateQrCode("hello", QRCodeGenerator.ECCLevel.Q);
var qr = new QRCode(data);
var bitmap = qr.GetGraphic(20, Color.Black, Color.White, icon: null, iconSizePercent: 12);
识别二维码:ZXing.Net 的 BitmapLuminanceSource 对图像质量敏感
不是所有 PNG/JPG 都能被正确识别——模糊、压缩失真、低对比度、倾斜角度 >15° 都会导致 reader.Decode() 返回 null。别急着换库,先检查输入源。
- 务必用
Bitmap加载原图,别用Image.FromFile()后强转,可能丢 Alpha 或色彩配置 - 小图(
Width )建议先 <code>Scale到 200+ 再识别,否则模块像素过少,解码器找不到定位图案 - 灰度预处理不是必须项,但若图中文字/边框干扰多,可用
BitmapExtensions.ToGrayscale()提前降噪
using var bitmap = new Bitmap("qrcode.png");
var luminance = new BitmapLuminanceSource(bitmap);
var binarizer = new HybridBinarizer(luminance);
var binBitmap = new BinaryBitmap(binarizer);
var result = reader.Decode(binBitmap); // result?.Text 才是内容
选 ZXing.Net 还是 QRCoder?看你要不要识别 + 多格式支持
QRCoder 只做生成,轻量快,API 简单;ZXing.Net 既能生又能识,还支持 DataMatrix、PDF417 等十多种码制。但体积大、初始化略慢,且识别对图像要求更“较真”。
- 纯生成需求(比如批量打单、网页导出):优先
QRCoder,NuGet 包小,GetGraphic()支持 SVG 输出 - 需要识别 + 生成 + 多码制兼容:必须用
ZXing.Net,但要注意它不支持 .NET 6+ 的默认Span<byte></byte>图像输入,仍依赖Bitmap - 两者都需手动处理 GDI+ 资源释放:
Bitmap.Dispose()必须调用,尤其在循环生成场景下,否则内存泄漏明显
Bitmap 是否为空,或者识别前没确认图像是否加载成功——这两步看着 trivial,但日志里一翻全是 ObjectDisposedException 或 NullReferenceException。


















