二维码容错等级详解(L、M、Q、H):到底该用哪一级?
打开任何一个二维码生成器,你都会看到标着 L、M、Q、H 的四个选项。大多数人直接用默认值完事——直到印出来的二维码扫不出来,或者市场部门在中间放了个 Logo 导致整个码报废。容错等级并不是一个装饰性设置。它决定了二维码能承受多大的物理损坏,并且与二维码能容纳多少数据直接此消彼长。
本文将解释这些等级在二维码规范(ISO/IEC 18004)内部到底做了什么,用真实数字说明它们如何改变容量,以及如何为你的使用场景选择正确的等级。
容错到底是什么
二维码不只是编码你的数据——它还会编码冗余信息,让读取器能够重建损坏或无法读取的部分。其机制是 Reed–Solomon 纠错码,与 CD、DVD、蓝光光盘和深空通信使用的是同一类算法。
生成二维码时,数据负载会被拆分成若干块,编码器为每一块计算一组纠错码字。如果读取器随后发现某些模块(黑白小方块)无法读取——因为划痕、咖啡渍、光线不好或者叠加的 Logo——它就会利用这些冗余码字,通过数学方法重建缺失的码字。
Reed–Solomon 码有一个有用的性质:要纠正 t 个位置未知的错误码字,需要 2t 个冗余码字。(如果已知损坏码字的位置——称为”擦除”(erasures)——则每个冗余码字可以修复一个。)容错等级本质上就是控制总码字预算中有多少分配给冗余、多少分配给负载。
四个等级的数字
ISO/IEC 18004 规范定义了四个容错等级,其大致恢复能力如下——即码字损坏后仍能完全恢复的比例:
| 等级 | 名称 | 恢复能力 |
|---|---|---|
| L | Low(低) | 约 7% 的码字 |
| M | Medium(中) | 约 15% 的码字 |
| Q | Quartile(四分之一) | 约 25% 的码字 |
| H | High(高) | 约 30% 的码字 |
这个单一百分比隐藏了两个重要的细节:
- 百分比针对的是码字,而不是模块面积。 流行的经验法则”H 级可以承受 30% 的码面被覆盖”在实践中大致成立,因为损坏通常是连续的,但正式限制针对的是损坏的码字。空间上聚集的损坏(比如 Logo)往往比随机散布的同等数量错误更容易恢复,因为擦除比位置未知的错误更容易纠正。
- 更高的等级会牺牲容量。 冗余越多,相同版本(尺寸)下留给负载的空间就越少。如果数据放不下,编码器就必须跳到更大的版本——模块更多、印刷更密、远距离更难扫描。
容量:各等级实际让你付出的代价
二维码有 40 种尺寸,称为版本。版本 1 是 21×21 个模块,之后每个版本每边增加 4 个模块,直到版本 40 的 177×177。下表列出了规范中三种代表性负载类型在四个等级下的最大字符容量。(字节模式覆盖任意 UTF-8 类二进制数据和典型 URL;字母数字模式覆盖 0–9 A–Z 空格 $%*+-./:;数字模式仅限数字。)
| 版本 | 模块 | 等级 | 数字 | 字母数字 | 字节 |
|---|---|---|---|---|---|
| 1 | 21×21 | L | 41 | 25 | 17 |
| 1 | 21×21 | M | 34 | 20 | 14 |
| 1 | 21×21 | Q | 27 | 16 | 11 |
| 1 | 21×21 | H | 17 | 10 | 7 |
| 5 | 37×37 | L | 255 | 154 | 106 |
| 5 | 37×37 | M | 202 | 122 | 84 |
| 5 | 37×37 | Q | 144 | 87 | 60 |
| 5 | 37×37 | H | 106 | 64 | 44 |
| 10 | 57×57 | L | 652 | 395 | 271 |
| 10 | 57×57 | M | 513 | 311 | 213 |
| 10 | 57×57 | Q | 364 | 221 | 151 |
| 10 | 57×57 | H | 288 | 174 | 119 |
| 20 | 97×97 | L | 2061 | 1249 | 858 |
| 20 | 97×97 | M | 1600 | 970 | 666 |
| 20 | 97×97 | Q | 1120 | 679 | 466 |
| 20 | 97×97 | H | 861 | 521 | 358 |
| 40 | 177×177 | L | 7089 | 4296 | 2953 |
| 40 | 177×177 | M | 5596 | 3391 | 2331 |
| 40 | 177×177 | Q | 3993 | 2420 | 1663 |
| 40 | 177×177 | H | 3057 | 1852 | 1273 |
仔细看版本 1:从 L 升到 H,字节容量从 17 降到 7——减少了 59%。对印刷品来说这笔交换通常值得,但代价是真实存在的。一个长 URL 在 M 级可以舒服地放进版本 4 的码,到了 H 级可能就得用版本 6,而更大的码意味着同样的印刷尺寸下模块更小。
更短的负载永远胜过更强的容错。 一个短 URL 用低版本、H 级的码,几乎总是比一个长 URL 用高版本、L 级的码更容易扫。如果你编码的是 URL,就用短域名或跳转链接。这一点比任何其他优化都重要。
印刷尺寸与扫描距离:10:1 法则
容错救不了一个小到根本无法分辨的码。广泛使用的现场经验是 10:1 比例:扫描距离不应超过码宽的 10 倍左右。有些资料认为 10:1 偏保守,并引用了在良好摄像头和光线下接近 15:1 的成功案例,但设计时应该以 10:1 为准。
- 名片上的码,宽 2 cm → 可靠扫描距离约 20 cm 以内
- 海报上的码,宽 10 cm → 可靠扫描距离约 1 m 以内
- 广告牌上的码,宽 1 m → 可靠扫描距离约 10 m 以内
两个相关的约束:
- 模块尺寸。 每个模块至少应约为 0.4 mm(2 mil 实在太小了;0.4 mm 是常见的印刷下限),这样手机摄像头才能分辨。对于版本 10 的码(57 个模块),仅数据区的最小物理尺寸就约为 2.3 cm。
- 静区(quiet zone)。 规范要求码四周留出至少 4 个模块宽度的空白边距。裁掉静区是印刷码失败最常见的原因之一,任何容错等级都无法弥补——读取器要靠静区来找到码的边缘。
为什么放 Logo 必须用 H 级
在二维码中央嵌入 Logo,正是 H 级存在的经典理由。Logo 物理上覆盖了模块,摧毁了下方的码字。H 级约 30% 的恢复预算才让这种做法得以存活。
Logo 叠加的实用规则:
- 用 H 级。 永远如此。在 M 级(约 15%),一个大小适中的 Logo 就已经吃掉了大部分预算。
- Logo 面积控制在整个码面的约 30% 以内——最好明显低于这个值,因为被覆盖的区域很少会干净地分布在各个码字块上。H 级下覆盖 20% 面积是稳妥的设计;28% 就是在赌博了。
- 保持在中央。 三个定位图案(角落的大方块)以及校正/对齐图案承载的结构数据,容错机制并不能以同样的方式保护。中央放置可以避开它们。
- 在真实手机、真实距离、糟糕光线下测试。 不只是拿你的旗舰机放在桌上测。摄像头平庸的旧款 Android 设备才是你要设计的下限。
注意,那些让你不选等级就直接放 Logo 的生成器,实际上是在赌你在别处选的等级。如果你设了 L 又加了 Logo,你就造出了一个经常失败但又不总是失败的码——这是最糟糕的结果,因为它能通过随手测试,却在实际使用中翻车。
到底该怎么选
L 级(约 7%)——仅限数字场景、图像渲染完美无缺的情况:App 间传递、屏幕显示、手机上展示生成的票券。像素干净意味着几乎不会出错,所以把预算花在容量和小尺寸上。其他场景很少适合用它。
M 级(约 15%)——干净印刷品的通用默认值:名片、产品包装、文档。能承受正常的使用磨损、轻微印刷缺陷和反光。大多数生成器默认选它,是有道理的。
Q 级(约 25%)——不放 Logo 的恶劣物理环境:工业标签、仓库货架、设备铭牌、经受风吹日晒的户外标牌。如果表面在正常使用中会被刮花、弄脏或部分遮挡,Q 就是主力选择。
H 级(约 30%)——Logo 叠加、非常恶劣的环境,或者扫描失败代价高昂的场合(支付码、安全关键标签)。当你必须印得很小、且预期摄像头质量较差时,也应选它。
决策树可以压缩为:纯数字 → L 或 M;干净印刷 → M;恶劣环境 → Q;Logo 或关键可靠性 → H。 无论选哪个等级:保持负载短、保留静区、遵守 10:1 距离法则。
自己动手验证
理论说完了,二维码容错其实很容易实证测试。用我们的 二维码生成器 把同一个 URL 按各等级生成一遍,对比一下:
- 分别用 L、M、Q、H 级生成码。注意模块密度的增加——那种视觉上的密度就是冗余。
- 打印 H 级的版本,用硬币或贴纸盖住中央(约 20% 面积),然后扫描。它应该还能扫出来。
- 对 L 级的版本做同样的操作。扫不出来。
- 拿 H 级的码逐步覆盖更多面积,直到扫描失败——你会发现实际上限接近理论值约 30%。
你还能直接看到容量代价:粘贴一个长 URL,观察每个等级各需要哪个版本(尺寸)。这个实验比任何表格都能更快地教会你这层取舍。
总结
- 二维码的容错是 Reed–Solomon 冗余;等级决定码字预算中冗余的占比:L ≈ 7%、M ≈ 15%、Q ≈ 25%、H ≈ 30% 的恢复能力。
- 更高的等级削减容量——在版本 1,H 能容纳的字节不到 L 的一半。
- 更短的负载胜过更强的容错;提高等级之前先缩短 URL。
- 按 10:1 距离法则设计印刷尺寸,永远不要裁掉 4 个模块宽度的静区。
- Logo 叠加 ⇒ H 级,Logo 面积控制在约 30% 以内,居中放置,在便宜手机上实测。
用 二维码生成器 生成几个变体,五分钟内你就能明显看出哪个等级适合你的场景。