ZXing.Net生成二维码需显式设置EncodingOptions的Height、Width(像素)、CharacterSet="UTF-8"、Margin=0或2,并用PNG格式保存;扫码时须将Bitmap转为Format24bppRgb格式再传入BitmapLuminanceSource。

用 ZXing.Net 生成二维码图片,别直接 new BarcodeWriter 就完事
生成二维码本身不难,但默认配置下容易导出模糊、尺寸不准或不兼容移动端扫描的图片。关键在 Bitmap 的 DPI 设置和编码参数。
常见错误是直接用 BarcodeWriter.Write("text") 返回 Bitmap,结果图片放大后边缘发虚,手机扫不出——因为 Bitmap 默认 96 DPI,而二维码需要像素级精确。
- 务必显式设置
Options.Height和Options.Width(单位:像素),不要依赖缩放 - 用
EncodingOptions指定CharacterSet = "UTF-8",否则中文乱码 - 推荐设置
Margin = 0或2,避免过宽白边导致扫码失败 - 导出 PNG 时用
bitmap.Save(stream, ImageFormat.Png),别用 JPEG(有压缩失真)
var writer = new BarcodeWriter
{
Format = BarcodeFormat.QR_CODE,
Options = new EncodingOptions
{
Height = 300,
Width = 300,
Margin = 2,
CharacterSet = "UTF-8"
}
};
var bitmap = writer.Write("https://example.com");
ZXing.Net 扫码时 Bitmap 转 LuminanceSource 容易崩,原因在颜色格式
扫码失败最常发生在图像预处理阶段:Bitmap 是 PixelFormat.Format32bppArgb,但 ZXing 的 BitmapLuminanceSource 默认只认 Format24bppRgb 或 Format8bppIndexed。直接传会抛 ArgumentException:“不支持的像素格式”。
- 先用
bitmap.Clone(new Rectangle(0, 0, bitmap.Width, bitmap.Height), PixelFormat.Format24bppRgb)转格式 - 如果图源来自摄像头(如
AForge.NET或MediaCapture),注意帧数据可能为 YUV,必须转 RGB 再构造成Bitmap - 小图(
using (var clone = bitmap.Clone(new Rectangle(0, 0, bitmap.Width, bitmap.Height), PixelFormat.Format24bppRgb))
{
var source = new BitmapLuminanceSource(clone);
var reader = new BarcodeReader();
var result = reader.Decode(source); // result?.Text 即识别内容
}
扫码性能差?别让 BarcodeReader 每次都重建
BarcodeReader 初始化成本高,内部做了大量缓存和解码器预热。在循环扫码(比如视频帧逐帧识别)中反复 new BarcodeReader(),CPU 占用飙升,帧率掉到 2fps 以下。
- 把
BarcodeReader实例作为类字段长期持有,复用它 - 必要时调用
reader.Options.TryHarder = true提升弱光/倾斜场景识别率,但会降速 30%~50% - 对同一张图多次识别,可提前用
source.Crop(x, y, width, height)锁定疑似区域,跳过全图扫描
中文扫码失败?不是编码问题,是字体渲染干扰了定位图案
如果二维码里含中文,且生成时用了非标准容错等级(如 ErrorCorrectionLevel.H),部分安卓扫码器(尤其是微信)会因定位角点被干扰而失败。这不是 ZXing 解码问题,而是生成端兼容性设计缺陷。
- 生成时固定用
ErrorCorrectionLevel.M(默认),别盲目设H - 避免在二维码周围加文字、logo 或阴影——哪怕 margin=0,叠加绘制也会污染 quiet zone
- 测试务必用真实手机扫,模拟器或截图识别通过 ≠ 现实可用
容错等级和 quiet zone 是硬约束,写代码时容易忽略,但一上线就卡住用户扫码流程。











