Каждый генератор QR по умолчанию выбирает режим кодирования за вас, и в большинстве случаев это значение подходит. Оно перестаёт быть подходящим в тот момент, когда вам нужен контроль над ним — числовой идентификатор рядом с кодом продукта, блок японского текста, который вы не хотите хранить в UTF-8, или полезная нагрузка, где вам нужны одинаковые байты каждый раз при генерации. Это руководство показывает, как установить режимы кодирования QR‑кода в Python явно, используя Aspose.BarCode for Python via .NET, так что один QR‑символ может содержать числовой сегмент, альфанумерический сегмент, байтовый сегмент и сегмент Канжи — каждый хранится в режиме, который ему лучше всего подходит.

Aspose.BarCode в своем API называет их режимами сжатия (QrExtCompactionMode), а спецификация QR называет их режимами кодирования. Это одни и те же четыре режима под разными названиями, и в этом руководстве используется термин “режим кодирования” на протяжении всего текста, поскольку именно он используется в спецификации и большинством Python‑библиотек QR.

Почему режимы кодирования QR влияют на размер символа и надежность сканирования

Физический размер QR‑кода определяется тем, сколько бит требуется для его полезной нагрузки, а количество бит на символ полностью зависит от режима кодирования, используемого для данного сегмента. Спецификация определяет четыре режима данных с заметно разной плотностью:

РежимНабор символовХранилищеСтоимость за символ
ЧисловойЦифры 0-93 цифры на 10 бит3,33 бита
Буквенно-цифровойЦифры, заглавные A-Z, пробел, $%*+-./:2 символа на 11 бит5,5 бита
БайтЛюбые 8-битные данные, обычно UTF-81 байт на 8 бит8 бит
КанжиДвухбайтовые символы Shift-JIS1 символ на 13 бит13 бит

30-значный идентификатор занимает примерно 100 бит в числовом режиме и 240 бит в байтовом режиме. Этот разрыв часто достаточно, чтобы поднять символ на несколько версий QR, а более высокая версия означает больше модулей в той же печатной области — меньшие модули и более низкую читаемость на камерах с низким разрешением, изогнутой упаковке и изношенных этикетках.

Автоматический выбор режима хорошо справляется с большинством полезных нагрузок. Он становится ограничивающим, когда вы знаете форму ваших данных, а анализатор — нет: длинная числовая последовательность, прерванная одной буквой, японский текст, для которого режим байтов потребует три байта UTF‑8 на символ, или идентификатор фиксированного формата, где требуется детерминированный вывод в разных версиях библиотеки.

Когда имеет смысл вручную задавать режим

Переключение режимов не бесплатно. На каждой границе сегмента записывается четырёхбитовый индикатор режима плюс поле количества символов от восьми до шестнадцати бит в зависимости от версии QR. Чрезмерное сегментирование полезной нагрузки может привести к большему символу, чем если позволить генератору решить.

Явное указание режима окупается, когда:

  • Полезная нагрузка содержит длинные однородные последовательности — 40‑значный серийный номер, абзац кандзи.
  • Вы кодируете японский текст и хотите использовать режим кандзи с 13 битами на символ вместо байтового режима с 24 битами.
  • Вам нужен воспроизводимый, байтово‑идентичный вывод для регрессионных тестов или проверки контрольной суммы.

Обычно не стоит добавлять сложность для коротких полезных нагрузок, данных, которые меняют тип каждые несколько символов, или URL‑адресов, которые автоматический анализ уже обрабатывает хорошо. Подраздел измерения ниже показывает, как проверить, в каком случае вы находитесь.

Два способа задать режимы кодирования QR в Python

Aspose.BarCode предлагает два пути к одному и тому же закодированному результату, и стоит знать, почему оба существуют, прежде чем писать код.

QrExtCodetextBuilderВстроенные EXTENDED селекторы
Режим задаётсяВызовы методов с перечислениямиМаркер обратного слеша в строке
Ошибки обнаруживаютсяНа месте вызоваТолько во время декодирования
Проблемы экранированияОтсутствуют\\ escaping, or raw strings
Оптимально дляКод приложенияКод текста из конфигурации, базы данных или другой системы

Builder является лучшим вариантом по умолчанию. QrExtCompactionMode.NUMERIC либо существует, либо сразу вызывает AttributeError, тогда как опечатка \numm в строке тихо превращается в полезные данные и проявляется только когда кто‑то сканирует метку. Оба подхода используют одинаковую настройку генератора QREncodeMode.EXTENDED, поэтому вы можете переключаться между ними, не меняя ничего дальше по цепочке.

Установите режимы кодирования QR‑кода в Python: пошагово

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() собирает их в строку расширенного формата, которую понимает генератор.

  1. Импортировать классы генерации.
  2. Создать QrExtCodetextBuilder.
  3. Добавить числовой сегмент с QrExtCompactionMode.NUMERIC.
  4. Добавить буквенно‑цифровой сегмент с QrExtCompactionMode.ALPHA_NUMERIC.
  5. Добавить байтовый сегмент с QrExtCompactionMode.BYTES.
  6. Добавить сегмент Kanji с QrExtCompactionMode.KANJI.
  7. Получить объединённый расширенный кодтекст.
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 задает режим кодирования для одного сегмента. Порядок имеет значение — декодер возвращает сегменты, объединённые в той последовательности, в которой вы их добавили.
  • Набор символов alphanumeric преднамеренно ограничен: цифры, заглавные буквы A‑Z, пробел и $%*+-./:. Поэтому ASPOSE2026 подходит для режима alphanumeric, а aspose2026 — нет. Строчные буквы не входят в набор, поэтому такой сегмент должен использовать BYTES. Передача строчных букв в ALPHA_NUMERIC — самая распространённая ошибка при таком способе установки режимов.
  • Сегмент Kanji использует символы начиная с \u3062, которые являются хираганой, а не настоящими кандзи. Режим Kanji охватывает диапазон двойных байтов Shift‑JIS, включающий кана, поэтому эти символы кодируются 13 битами каждый, вместо 24 бит, которые занял бы режим байтов в UTF‑8.
  • get_extended_codetext() генерирует строку, которую генератор разбирает в режиме EXTENDED. Вывести её с помощью repr() стоит один раз — это покажет синтаксис селектора, который выдаёт builder, и именно его вручную пишет следующий подраздел.

3. Установить режим кодирования Inline, без Builder

Когда кодовый текст берётся из внешнего источника, а не из вашего кода Python, вы можете задать режим каждого сегмента напрямую с помощью селектора. Каждый маркер, начинающийся с обратного слеша, управляет всеми символами до появления следующего маркера:

SelectorУстанавливает режим на
\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. Создать QR‑штрих-код в режиме EXTENDED

Установка режимов для каждого сегмента не оказывает влияния, пока генератор не будет проинструктирован считывать их. Без QREncodeMode.EXTENDED информация о сегментах игнорируется, а маркеры селектора кодируются как буквальный текст полезной нагрузки.

  1. Создайте BarcodeGenerator с EncodeTypes.QR и расширенным кодовым текстом.
  2. Установите encode_mode в QREncodeMode.EXTENDED.
  3. Настройте разрешение, а при необходимости уровень коррекции ошибок и отступ.
  4. Сохраните штрих‑код в без потерь 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. Избегайте JPEG для любой 2D‑символики — артефакты сжатия размывают сетку модулей, которую считывает декодер.

5. Проверьте, что режим кодирования был применён

Успешное создание ничего не доказывает относительно того, вступили ли в силу режимы per‑segment. Шаг декодирования — это то, что отделяет правильно закодированный символ от того, который несёт маркеры селектора в виде данных.

  1. Инициализируйте BarCodeReader с путем к файлу и DecodeType.QR.
  2. Материализуйте результаты, чтобы неудачное чтение было видно.
  3. Сравните декодированный текст с ожидаемым объединением.
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. Измерьте, помогло ли ручная установка режима

Установка режима кодирования вручную — это оптимизация, поэтому измерьте её, а не делайте предположений. Сгенерируйте одинаковый payload обоими способами и сравните:

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 и примените её перед любым вызовом генерации или распознавания.

Бесплатные дополнительные ресурсы

Заключение

Настройка режимов кодирования QR‑кода в Python сводится к двум вопросам: какой сегмент получает какой режим и как сообщить генератору учитывать этот выбор. QrExtCodetextBuilder и QrExtCompactionMode отвечают на первый вопрос в коде приложения; QREncodeMode.EXTENDED отвечает на второй на уровне генератора. В этом руководстве рассматриваются как API билдера, так и синтаксис встроенного селектора, который он генерирует, создающий QR‑символ из четырёх сегментов, проверяющий декодированную полезную нагрузку и измеряющий разницу в размере по сравнению с автоматическим режимом.

Предпочтительно использовать builder для кода приложения — он ловит ошибки режима на месте вызова, а не в сканере. И сохраняйте шаг измерения. Установка режима вручную действительно выигрывает на длинных однородных полезных нагрузках и приводит к чистому убытку на коротких смешанных, где накладные расходы на переключение режимов превышают экономию. Сгенерируйте оба варианта, сравните количество модулей и позвольте результату решить, какой код поддерживать.

Часто задаваемые вопросы

  1. Что такое режим кодирования QR‑кода и зачем он нужен?
    Режим кодирования указывает генератору QR, как обрабатывать сегмент данных — числовой, буквенно‑цифровой, байтовый или Канжи. Каждый режим имеет разную плотность данных, поэтому правильный выбор режима для каждого сегмента позволяет минимизировать версию QR и, соответственно, размер символа. Aspose.BarCode называет их режимами сжатия; спецификация QR называет их режимами кодирования.

  2. Какие режимы кодирования поддерживает QrExtCompactionMode? QrExtCompactionMode предоставляет NUMERIC, ALPHA_NUMERIC, BYTES и KANJI, соответствующие четырём режимам данных QR, определённым в ISO/IEC 18004.

  3. Стоит ли использовать QrExtCodetextBuilder или встроенные EXTENDED селекторы для установки режима? Используйте builder для кода приложения. Он проверяется типами, избегает ошибок экранирования обратных слешей и собирает extended codetext за вас. Встроенные селекторы полезны, когда codetext поступает из конфигурации, базы данных или другой системы, которая не может вызвать builder.

  4. Чем режим кодирования EXTENDED отличается от стандартного режима кодирования QR? EXTENDED режим заставляет генератор читать кодовый текст как серию предопределённых сегментов, каждый со своим режимом кодирования, вместо автоматического определения режима для всей строки.

  5. Могу ли я установить разные режимы кодирования для разных частей одного QR‑кода? Да. Добавьте несколько сегментов в QrExtCodetextBuilder, каждый с другим QrExtCompactionMode, и построитель создаст единый расширенный кодовый текст, охватывающий все их.

  6. Совместим ли QR‑код, сгенерированный с использованием смешанных режимов кодирования, со стандартными считывателями? Да. Много‑сегментное кодирование является частью спецификации QR, поэтому любой совместимый сканер правильно декодирует полезную нагрузку и возвращает объединённые данные.

  7. Всегда ли ручная установка режима кодирования приводит к более маленькому QR‑коду? Нет. Каждая граница сегмента требует индикатора режима и поля количества символов, поэтому разбивание данных на множество коротких сегментов может увеличить размер символа. Ручной выбор режима оправдывается при длинных однородных последовательностях числовых или кандзи‑данных.

  8. Нужна ли лицензия для установки режимов кодирования QR с помощью QrExtCodetextBuilder? Вы можете оценивать API без лицензии, но с ограничениями оценки. Бесплатная временная лицензия с сайта Aspose снимает эти ограничения во время тестирования, а для использования в продакшене требуется полная лицензия.

  9. Какую версию Aspose.BarCode for python-net поддерживает эти API? QrExtCodetextBuilder, QrExtCompactionMode и QREncodeMode.EXTENDED доступны в Aspose.BarCode for Python via .NET 26.6 и более поздних версиях.

Читать далее