qrcoder仅支持二维码生成,不具备解码能力,必须配合zxing.net扫描;生成需经qrcodegenerator→qrcode两步,扫码需确保图像尺寸≥200、高对比度、正向摆放,并合理设置容错等级与logo尺寸。

QRCoder 是目前 C# 中生成二维码最轻量、稳定且跨平台兼容的选择;但扫描必须用 ZXing.Net,两者职责完全不同,混用或跳过中间步骤会导致空白图、扫码失败或运行时异常。
为什么不能只用 QRCoder 扫码?
QRCoder 是纯生成库,不包含任何解码能力。它返回的是 QRCodeData(逻辑矩阵)或 Bitmap(图像),没有识别引擎。试图对它调用“Decode”会编译报错或返回 null。
- 常见错误现象:
NullReferenceException或reader.Decode(...) returns null,本质是传入了非位图对象(比如直接传QRCodeData)或图像质量不达标 - ZXing.Net 的
BitmapLuminanceSource要求输入是真实Bitmap实例,不能是Image、Stream或byte[]直接强转 - 若用
Image.FromFile()加载再转Bitmap,可能丢失 Alpha 通道或 DPI 信息,导致定位图案识别失败 - 推荐做法:用
new Bitmap(path)或new Bitmap(stream)构造,确保底层像素可读
QRCoder 生成二维码必须走两步:QRCodeGenerator → QRCode
跳过任一环节都会出问题——不是编译不过,就是运行时输出空白、黑块或尺寸为 0×0。
-
QRCodeGenerator.CreateQrCode()只生成编码数据(QRCodeData),不含图像信息;传参不合法(如内容超长+纠错等级太低)会抛ArgumentException: Data too long -
QRCode或PngByteQRCode才负责把QRCodeData渲染成图;漏掉这步,GetGraphic()无处调用 - 中文内容无需手动 UTF-8 编码,
QRCodeGenerator默认按 UTF-8 处理,但若传入byte[]必须自己保证编码正确 - 关键参数建议:
quietZonePercent = 15(留白边防裁剪)、moduleSize = 20(模块像素,30 在高密场景可能溢出)
ZXing.Net 扫描失败的三大硬性条件
不是库不行,而是输入图像没达标。90% 的 “扫不出来” 都卡在这三处。
- 图像尺寸太小:
Width 或 <code>Height 时,定位图案(Finder Pattern)模块数不足,解码器无法锁定坐标;应先 <code>Scale到 ≥200 再识别 - 对比度与清晰度不足:模糊、JPG 压缩失真、轻微倾斜(>15°)、反光/阴影都会让
HybridBinarizer失效;别依赖自动灰度,优先用原图 - 非正向摆放:ZXing 默认不旋转尝试,若图是倒置或侧翻,
Decode()直接返回 null;需预处理旋转或启用TryHarder = true(性能下降 3–5 倍) - 进阶提示:对低质量图,可用
BitmapExtensions.ToGrayscale()+ThresholdBinarizer替代默认HybridBinarizer,提升抗噪能力
加 Logo 后扫码失败?不是加得不对,是容错没配够
QRCoder 不支持原生 Logo 嵌入,所有“加图”都是后期用 GDI+ 合成。失败主因不是位置偏移,而是纠错等级不足 + Logo 覆盖关键区域。
- 必须用
QRCodeGenerator.ECCLevel.Q或H——L级(7% 容错)加图后基本必挂,Q级(25%)是底线 - Logo 尺寸不能超二维码宽高的 25%,计算公式:
int safeSize = (int)(qrImage.Width * 0.25);超限会压住 Finder Pattern 边框 - Logo 必须为透明背景 PNG,且为正方形;白底图会把二维码白色模块“染黑”,形成伪定位块,干扰解码
- 合成时务必新建
Bitmap画布,设置SmoothingMode.AntiAlias和InterpolationMode.HighQualityBicubic,否则边缘锯齿会放大识别误差
真正难的不是写几行生成代码,而是理解 QR 标准里“定位图案不可覆盖”“纠错能力与内容长度强相关”这些隐性约束。加一个 Logo 或换一种容错等级,背后都是对模块分布和 Reed-Solomon 编码边界的实际影响。忽略这些,再短的代码也扫不出。











