每个 QR 生成器默认会为您选择一种编码模式,而大多数情况下这个默认是合适的。当您需要对其进行控制时,这种默认就不再合适——例如在产品代码旁的数字 ID、您不想以 UTF-8 存储的日文文本块,或是每次生成时都需要相同字节的负载。本指南展示了如何 在 Python 中显式设置 QR 码编码模式,使用 Aspose.BarCode for Python via .NET,使单个 QR 符号能够携带数值段、字母数字段、字节段和汉字段——每个段都以最适合的模式存储。
Aspose.BarCode 在其自己的 API 名称中将这些 compaction modes 称为 (QrExtCompactionMode),而 QR 规范本身将它们称为 encoding modes。它们是相同的四种模式,只是名称不同,本指南在整个内容中使用 “encoding mode”,因为这是规范和大多数 Python QR 库使用的术语。
为什么 QR 编码模式会影响符号大小和扫描可靠性
QR 码的实际尺寸取决于其负载所需的位数,而每个字符的位数完全取决于该段使用的编码模式。规范定义了四种数据模式,它们的密度差异显著:
| 模式 | 字符集 | 存储 | 每字符成本 |
|---|---|---|---|
| 数值 | 数字 0-9 | 每 10 位 3 个数字 | 3.33 位 |
| 字母数字 | 数字、大写字母 A-Z、空格、$%*+-./: | 每 11 位 2 个字符 | 5.5 位 |
| 字节 | 任意 8 位数据,通常为 UTF-8 | 每 8 位 1 字节 | 8 位 |
| 汉字 | Shift-JIS 双字节字符 | 每 13 位 1 个字符 | 13 位 |
30位标识符在数字模式下大约需要 100 位,在字节模式下大约需要 240 位。这个差距通常足以将符号提升几个 QR 版本,而更高的版本意味着在相同的打印面积内有更多的模块——模块更小,在低分辨率摄像头、弯曲包装和磨损标签上读取率更低。
自动模式选择能够很好地处理大多数负载。当您了解数据的形状而分析器不了解时,它会受到限制:被单个字母打断的长数字序列、字节模式会为每个字符消耗三个 UTF-8 字节的日文文本,或是您希望在库版本之间获得确定性输出的固定格式标识符。
手动设置模式值得的情况
模式切换不是免费的。每个段落边界都会写入一个四位的模式指示符,加上一个根据 QR 版本而定的八到十六位的字符计数字段。对负载进行过度分段可能会产生比让生成器自行决定更大的符号。
显式设置模式在以下情况下有益:
- 负载包含长的同质运行——一个40位的序列号,一段汉字段落。
- 您正在对日文文本进行编码,并希望使用每字符13位的汉字模式,而不是每字符24位的字节模式。
- 您需要可重现、字节完全相同的输出,以用于回归测试或校验和验证。
通常情况下,对于短负载、每隔几个字符就切换类型的数据或 URL,增加复杂性并不值得,因为自动分析已经能够很好地处理这些情况。下面的测量子章节展示了如何检查您所处的情况。
两种在 Python 中设置 QR 编码模式的方法
Aspose.BarCode 提供两种实现相同编码结果的方式,在编写代码之前了解它们共存的原因是值得的。
QrExtCodetextBuilder | 内联 EXTENDED 选择器 | |
|---|---|---|
| 模式设置方式 | 使用枚举值的方法调用 | 字符串中的反斜杠标记 |
| 捕获的错误 | 在调用点 | 仅在解码时 |
| 转义关注点 | 无 | \\ 转义,或原始字符串 |
| 最佳适用场景 | 应用程序代码 | 来自配置、数据库或其他系统的代码文本 |
构建器是更好的默认选项。 QrExtCompactionMode.NUMERIC 要么存在,要么立即引发 AttributeError,而在字符串中误写为 \numm 则会悄悄变成负载数据,只有在有人扫描标签时才会显现。 这两种方式都使用相同的 QREncodeMode.EXTENDED 生成器设置,因此可以在它们之间切换,而无需更改下游的任何内容。
在 Python 中设置 QR 码编码模式:逐步指南
1. 安装并准备开发环境
Aspose.BarCode for Python via .NET 是一个跨平台库,支持生成、识别和操作超过 50 种符号,包括 QR。可从 PyPI 安装:
pip install aspose-barcode-for-python-via-net
确认版本,因为这些 API 需要 26.6 或更高版本:
pip show aspose-barcode
然后验证导入是否解析成功。该包绑定到 .NET 运行时,因此成功的导入比磁盘上文件的存在提供了更多信息:
from aspose.barcode.generation import QREncodeMode, QrExtCompactionMode
print("Aspose.BarCode imported successfully.")
print("EXTENDED mode available:", hasattr(QREncodeMode, "EXTENDED"))
print("Encoding modes:", [m for m in dir(QrExtCompactionMode) if m.isupper()])
Output:
Aspose.BarCode imported successfully.
EXTENDED mode available: True
Encoding modes: ['ALPHA_NUMERIC', 'AUTO', 'BYTES', 'KANJI', 'NUMERIC']
如果缺少 EXTENDED,则表示您使用的版本早于 26.6,需要在继续之前进行升级。
如果您有许可证文件,请在应用程序启动时一次性应用它,在进行任何生成或识别调用之前:
from aspose.barcode import License
license = License()
license.set_license("Aspose.BarCode.Python.NET.lic")
2. 使用 QrExtCodetextBuilder 为每个段设置编码模式
QrExtCodetextBuilder 保存一个有序的段列表。每次调用都会将数据与应存储的编码模式一起追加,并且 get_extended_codetext() 会将它们组装成生成器能够理解的扩展格式字符串。
- 导入生成类。
- 创建一个
QrExtCodetextBuilder。 - 使用
QrExtCompactionMode.NUMERIC添加数值段。 - 使用
QrExtCompactionMode.ALPHA_NUMERIC添加字母数字段。 - 使用
QrExtCompactionMode.BYTES添加字节段。 - 使用
QrExtCompactionMode.KANJI添加汉字段。 - 检索组合的扩展码文本。
from aspose.barcode.barcoderecognition import BarCodeReader, DecodeType
from aspose.barcode.generation import (
BarcodeGenerator,
EncodeTypes,
QREncodeMode,
QrExtCodetextBuilder,
QrExtCompactionMode,
)
# Instantiate the Builder.
text_builder = QrExtCodetextBuilder()
# Numeric Segment — 3 Digits per 10 Bits.
text_builder.add_codetext_with_compaction_mode(
QrExtCompactionMode.NUMERIC, "1234567"
)
# Alphanumeric Segment — Uppercase and Digits Only, 2 Characters per 11 Bits.
text_builder.add_codetext_with_compaction_mode(
QrExtCompactionMode.ALPHA_NUMERIC, "ASPOSE2026"
)
# Byte Segment — Lowercase Forces Byte Mode, 8 Bits per Character.
text_builder.add_codetext_with_compaction_mode(
QrExtCompactionMode.BYTES, "aspose2026"
)
# Kanji Segment — Shift-JIS Double-Byte Characters, 13 Bits Each.
text_builder.add_codetext_with_compaction_mode(
QrExtCompactionMode.KANJI,
"\u3062\u3063\u3064\u3065\u3066\u3067\u3068\u3069\u306A",
)
# Assemble the Final Extended Codetext.
codetext = text_builder.get_extended_codetext()
print("Extended codetext:", repr(codetext))
解释
- 每个
add_codetext_with_compaction_mode调用为一个段设置编码模式。顺序很重要——解码器会按照你添加的顺序返回连接后的段。 - 字母数字集被刻意设得很窄:数字、 大写 A‑Z、空格以及
$%*+-./:。这就是为什么ASPOSE2026能符合字母数字模式,而aspose2026则不行。小写字母不在该集合中,因此该段必须使用BYTES。在这种方式下将小写字母传给ALPHA_NUMERIC是最常见的错误。 - Kanji 段使用
\u3062起始的字符,这些是平假名而非真正的汉字。Kanji 模式覆盖 Shift-JIS 双字节范围,其中包括假名,因此这些字符每个以 13 位编码,而不是字节模式下以 UTF-8 编码时的 24 位。 get_extended_codetext()生成生成器在 EXTENDED 模式下解析的字符串。使用repr()打印一次是值得的——它会显示构建器输出的选择器语法,这正是下一小节手动编写的内容。
3. 在不使用 Builder 的情况下内联设置编码模式
当代码文本来源于 Python 代码之外时,您可以使用选择器直接为每个段设置模式。每个以反斜杠为前缀的标记会控制其后的所有字符,直至出现下一个标记为止:
| 选择器 | 设置模式为 |
|---|---|
\num | 数字 |
\alnum | 字母数字 |
\byte | 字节,UTF-8 |
\kanji | 汉字,Shift-JIS |
\auto | 自动模式选择 |
# Equivalent to the Builder Output Above, Written Directly.
codetext = (
r"\num1234567"
r"\alnumASPOSE2026"
r"\byteaspose2026"
"\\kanji\u3062\u3063\u3064\u3065\u3066\u3067\u3068\u3069\u306A"
)
注意转义。在普通的 Python 字符串中,"\num" 并不是选择器——它是一个换行符后跟 um。原始字符串(r"...")可以避免此问题,但原始字符串也会阻止 \u 转义,这就是上面的汉字行使用带有 \\kanji 的常规字符串的原因。这个转义陷阱是倾向于在第 2 节中使用构建器的实际理由。
4. 生成 EXTENDED 模式的 QR 条码
设置每段模式在生成器被指示读取它们之前不会产生任何效果。没有 QREncodeMode.EXTENDED,段信息会被忽略,选择器标记会被编码为字面负载文本。
- 使用
EncodeTypes.QR和扩展的代码文本创建BarcodeGenerator。 - 将
encode_mode设置为QREncodeMode.EXTENDED。 - 配置分辨率,并可选地设置错误更正级别和边距。
- 将条形码保存为无损 PNG。
# Create the QR Generator with the Extended Codetext.
gen = BarcodeGenerator(EncodeTypes.QR, codetext)
# Switch to EXTENDED Mode So the Per-Segment Modes Are Respected.
gen.parameters.barcode.qr.encode_mode = QREncodeMode.EXTENDED
# Render at Print Resolution Rather Than Upscaling Later.
gen.parameters.resolution = 300
# Save the Generated QR Code.
gen.save("extended_qr.png")
print("QR code generated and saved as extended_qr.png")
说明
gen.parameters.barcode.qr.encode_mode = QREncodeMode.EXTENDED是激活段解析的行。省略它,生成器会产生一个有效的、可扫描的 QR 码,其中包含文字\num1234567...—— 这就是为什么下一小节进行验证而不是假设的原因。gen.parameters.resolution = 300以打印分辨率渲染。面向标签打印机或包装艺术的符号应以最终尺寸生成,而不是事后放大,这会使模块边缘变得柔和。save写入无损 PNG。避免对任何 2D 符号使用 JPEG——其压缩伪影会模糊解码器采样的模块网格。
5. 验证已应用编码模式
成功的生成并不能证明每段模式是否生效。解码步骤是将正确编码的符号与携带选择器标记作为数据的符号区分开的关键。
- 使用文件路径和
DecodeType.QR初始化BarCodeReader。 - 实例化结果,以便能够看到读取失败的情况。
- 将解码后的文本与预期的拼接结果进行比较。
EXPECTED = (
"1234567"
"ASPOSE2026"
"aspose2026"
"\u3062\u3063\u3064\u3065\u3066\u3067\u3068\u3069\u306A"
)
# Initialise the QR Code Reader.
reader = BarCodeReader("extended_qr.png", DecodeType.QR)
results = list(reader.read_bar_codes())
if not results:
raise ValueError("No QR code was detected in extended_qr.png.")
for result in results:
decoded = result.code_text
print("BarCode CodeText:", decoded)
if "\\num" in decoded or "\\alnum" in decoded:
print("Selectors were encoded literally — check that encode_mode is EXTENDED.")
elif decoded == EXPECTED:
print("Verified: all four segments decoded and concatenated as expected.")
else:
print("Mismatch. Expected:", EXPECTED)
说明
DecodeType.QR限制识别仅针对 QR 符号,这比扫描所有受支持的条码更快,并且可以防止将畸形符号错误解码为其他内容。list(...)使失败情况明确。识别失败会返回一个空的可迭代对象,而不是抛异常,因此对失败读取的未加防护的for循环会静默结束并被视为成功。- 检查字面量
\num可以捕获此工作流中最常见的错误:正确设置了段,但忘记设置encode_mode。 - 解码后的负载是原始段的串联,所有模式信息在编码时已被消耗。编码模式是对编码器的指令,而不是数据的一部分。
6. 衡量手动设置模式是否有帮助
手动设置编码模式是一种优化,因此应进行测量而不是假设。以两种方式生成相同的负载并进行比较:
RAW = "1234567ASPOSE2026aspose2026"
# Automatic Mode Selection.
auto = BarcodeGenerator(EncodeTypes.QR, RAW)
auto.save("qr_auto.png")
# Manually Set Modes per Segment.
builder = QrExtCodetextBuilder()
builder.add_codetext_with_compaction_mode(QrExtCompactionMode.NUMERIC, "1234567")
builder.add_codetext_with_compaction_mode(QrExtCompactionMode.ALPHA_NUMERIC, "ASPOSE2026")
builder.add_codetext_with_compaction_mode(QrExtCompactionMode.BYTES, "aspose2026")
manual = BarcodeGenerator(EncodeTypes.QR, builder.get_extended_codetext())
manual.parameters.barcode.qr.encode_mode = QREncodeMode.EXTENDED
manual.save("qr_manual.png")
print("Compare qr_auto.png and qr_manual.png — count modules along one edge.")
计算每个图像一边的模块数。QR 版本 n 符号是 17 + 4n 模块的正方形,因此版本 2 为 25×25,版本 3 为 29×29。如果两者落在同一版本,自动分析已经找到了最佳分段,手动设置模式只会增加维护负担而没有收益。在发布前发现这一点是有价值的结果,而不是浪费的步骤。
获取免费许可证
Aspose 提供临时免费许可证,可解除评估限制并解锁全部功能以进行测试。请从 Aspose 临时许可证页面 请求一个,并在任何生成或识别调用之前应用它。
免费的额外资源
结论
在 Python 中设置 QR 码编码模式归结为两个问题:哪个段落使用哪种模式,以及如何让生成器遵循该选择。QrExtCodetextBuilder 和 QrExtCompactionMode 在应用代码中回答第一个问题;QREncodeMode.EXTENDED 在生成器层面回答第二个问题。本指南涵盖了构建器 API 以及它生成的内联选择器语法,生成了一个四段的 QR 符号,验证了解码后的负载,并测量了相对于自动模式的大小差异。
在应用代码中首选使用构建器——它可以在调用点捕获模式错误,而不是在扫描器处。并且保留测量步骤。手动设置模式在长的同质负载上是真正的优势,而在短的混合负载上则会导致净损失,因为模式切换的开销超过了节省。生成两者,比较模块计数,让结果决定你维护哪段代码。
FAQs
什么是 QR 码编码模式,我为什么要使用它? 编码模式告诉 QR 生成器如何处理一段数据——数字、字母数字、字节或汉字。每种模式具有不同的数据密度,因此为每段数据选择合适的模式可以保持 QR 版本(从而符号)尽可能小。Aspose.BarCode 将这些称为压缩模式;QR 规范则称其为编码模式。
QrExtCompactionMode 支持哪些编码模式?
QrExtCompactionMode提供NUMERIC、ALPHA_NUMERIC、BYTES和KANJI,匹配 ISO/IEC 18004 中定义的四种 QR 数据模式。我应该使用 QrExtCodetextBuilder 还是内联 EXTENDED 选择器来设置模式? 对于应用程序代码,请使用构建器。它经过类型检查,避免了反斜杠转义错误,并为您组装扩展的代码文本。当代码文本来自配置、数据库或其他无法调用构建器的系统时,内联选择器很有用。
EXTENDED 编码模式与标准 QR 编码模式有何不同? EXTENDED 模式使生成器将代码文本视为一系列预定义的段,每个段都有其自己的编码模式,而不是在整个字符串上运行自动模式检测。
我可以为同一个 QR 码的不同部分设置不同的编码模式吗? 是的。向
QrExtCodetextBuilder添加多个段,每个段使用不同的QrExtCompactionMode,构建器会生成一个覆盖所有段的单一扩展码文本。使用混合编码模式生成的 QR 码是否兼容标准阅读器?
是的。多段编码是 QR 规范的一部分,因此任何符合规范的扫描器都会正确解码负载并返回连接后的数据。手动设置编码模式是否总是会产生更小的 QR 码?
不。每个段边界都会消耗一个模式指示符和字符计数字段,因此将数据拆分为许多短段可能会使符号变大。手动模式选择在长且同质的数字或汉字数据序列中才有优势。我需要许可证才能使用 QrExtCodetextBuilder 设置 QR 编码模式吗? 您可以在没有许可证的情况下评估 API,但受评估限制。来自 Aspose 网站的免费临时许可证可在测试期间解除这些限制,生产使用则需要完整许可证。
哪个版本的 Aspose.BarCode for python-net 支持这些 API?
QrExtCodetextBuilder,QrExtCompactionMode, andQREncodeMode.EXTENDED在 Aspose.BarCode for Python via .NET 26.6 及更高版本中可用。
