Как исправить проблему с большими пустыми полями и маленьким размером QR-кода при печати в 1С

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При формировании печатных форм в системе «1С:Предприятие» разработчики часто сталкиваются с необходимостью вывода двумерных штрихкодов (QR-кодов). Использование стандартной нативной компоненты печати штрихкодов от фирмы «1С» является наиболее предпочтительным решением, так как она кроссплатформенная и стабильно работает как под Windows, так и под Linux.

Однако при выводе длинных строк (например, банковских реквизитов для платежных поручений по стандарту ГОСТ, маркировки «Честный Знак» или сложных URL-адресов длиной более 150–200 символов) возникает неприятная проблема. Компонента генерирует изображение, в котором сам QR-код оказывается очень маленьким, а вокруг него образуются огромные пустые белые поля. При выводе на печать в ячейку табличного документа со свойством «Пропорционально» такой код сжимается еще сильнее, его физический размер уменьшается, и оптические сканеры или мобильные приложения попросту отказываются его распознавать. Выясним причину этого поведения и подробно разберем, как его исправить.

Почему возникает проблема «лишнего фона» и мелкого штрихкода

Для начала проанализируем физику процесса генерации растрового изображения штрихкода. Любой QR-код состоит из сетки квадратных элементов (модулей). Чтобы код гарантированно и без искажений считывался оптическими устройствами, каждый такой модуль на готовой картинке должен состоять из строго целого количества пикселей (например, 1, 2, 3, 4 пикселя и так далее). Дробное количество пикселей на элемент недопустимо, так как при масштабировании возникнет эффект размытия (антиалиасинг), границы модулей потеряют четкость, и штрихкод станет нечитаемым.

Когда мы передаем компоненте целевой размер области (например, ширину 160 пикселей и высоту 140 пикселей), алгоритм выполняет следующие расчеты:

  1. Определяет минимальную версию (плотность модулей) QR-кода, в которую физически поместится переданный объем данных. Для длинной строки это будет плотная сетка.
  2. Рассчитывает максимально возможный целый масштаб для одного модуля, при котором весь QR-код поместится в рамки 160x140.
  3. Если при масштабе в 2 пикселя на модуль размер кода превышает 160x140 пикселей, компонента вынуждена применить масштаб в 1 пиксель на модуль.
  4. В результате размер значащей части QR-кода получается, например, всего 72x72 пикселя.

В старых версиях компоненты (до внедрения оптимизаций) поведение было следующим: если запрошен холст размером 160x140, компонента возвращала картинку размером ровно 160x140 пикселей. Значащий QR-код размером 72x72 пикселя центрировался на этом холсте, а все оставшееся пространство заливалось белым цветом фона. Когда платформа 1С помещала эту картинку в ячейку макета со свойством РазмерКартинки = Пропорционально, она пропорционально сжимала весь холст (вместе с полями). Физический размер самого кода на бумаге становился микроскопическим, а плотность пикселей падала ниже допустимого предела для сканеров.

Рассмотрим два надежных способа решения этой проблемы: современный (с помощью встроенного свойства компоненты) и альтернативный (для старых версий платформы и библиотек).

Решение 1. Использование встроенного свойства «УбратьЛишнийФон»

В современных версиях нативной компоненты генерации штрихкодов от 1С (начиная с версий БПО 9.0.9 / 9.0.10) разработчики добавили специальное свойство — УбратьЛишнийФон (в англоязычном варианте RemoveExtraBackground). Это свойство имеет тип Булево.

Если установить это свойство в значение Истина, компонента изменит алгоритм формирования итогового файла. Она рассчитает оптимальный размер значащей части штрихкода (в нашем примере — 72x72 пикселя) и вернет картинку именно этого («обрезанного») размера, проигнорировав пустые поля по краям. При выводе в табличный документ со свойством Пропорционально такая картинка автоматически растянется силами платформы на всю доступную область ячейки макета, обеспечивая максимальный физический размер элементов штрихкода.

Разберем по шагам, как применить это свойство в коде при различных сценариях интеграции.

Вариант А. Работа через Библиотеку стандартных подсистем (БСП) или Библиотеку подключаемого оборудования (БПО)

Если в вашей конфигурации генерация штрихкодов выполняется через стандартные общие модули, параметры штрихкода обычно передаются в виде структуры. Достаточно добавить новое свойство в структуру параметров перед вызовом функции формирования:


ПараметрыШтрихкода = Новый Структура;
ПараметрыШтрихкода.Вставить("Ширина", 160);
ПараметрыШтрихкода.Вставить("Высота", 140);
ПараметрыШтрихкода.Вставить("ТипКода", 16); // 16 соответствует QR-коду
ПараметрыШтрихкода.Вставить("ОтображатьТекст", Ложь);
ПараметрыШтрихкода.Вставить("УбратьЛишнийФон", Истина); // Исключаем пустые поля

ДанныеQRКода = УправлениеПечатью.ДанныеQRКода(ЗначениеСтроки, ПараметрыШтрихкода);
Если ДанныеQRКода <> Неопределено Тогда
    КартинкаQRКода = Новый Картинка(ДанныеQRКода);
    // Помещаем полученную картинку в область макета или элемент формы
КонецЕсли;

Вариант Б. Прямое обращение к внешней компоненте 1С

Если вы подключаете внешнюю компоненту печати штрихкодов напрямую из общего макета, свойство устанавливается непосредственно у созданного COM-объекта или Native-объекта компоненты:


Если ПодключитьВнешнююКомпоненту("ОбщийМакет.КомпонентаПечатиQRКода", "QR") Тогда
    ГенераторШК = Новый("AddIn.QR.QRCodeExtension");
    
    // Задаем исходный текст и параметры
    ГенераторШК.Текст = "Строка длинного текста для QR-кода...";
    ГенераторШК.Ширина = 160;
    ГенераторШК.Высота = 140;
    
    // Включаем опцию удаления лишних полей
    ГенераторШК.УбратьЛишнийФон = Истина;
    
    // Получаем бинарные данные картинки штрихкода
    ДанныеКартинки = ГенераторШК.ПолучитьКартинку();
    Если ДанныеКартинки <> Неопределено Тогда
        АдресКартинки = ПоместитьВоВременноеХранилище(ДанныеКартинки);
    КонецЕсли;
КонецЕсли;

Решение 2. Обходной путь для старых версий (метод минимальных габаритов)

Бывают ситуации, когда конфигурация находится на старой платформе или используются архивные релизы БСП/БПО, в которых компонента штрихкодирования еще не поддерживает свойство УбратьЛишнийФон. В этом случае можно воспользоваться математическим обходным путем, который основывается на свойствах самой компоненты.

Проанализируем алгоритм работы компоненты без использования флага удаления фона. У объекта внешней компоненты после передачи строки текста заполняются свойства только для чтения: МинимальнаяШиринаКода и МинимальнаяВысотаКода. Эти свойства содержат точный размер значащей части QR-кода в пикселях при текущей плотности данных без учета полей.

Если мы запросим генерацию картинки именно под этот минимальный размер, компонента создаст файл пиксель-в-пиксель, в котором не будет ни одного лишнего белого пикселя по краям. Разберем, как реализовать этот алгоритм по шагам:

  1. Инициализируем внешнюю компоненту в коде.
  2. Передаем компоненте текст, который необходимо закодировать.
  3. Считываем значения свойств МинимальнаяШиринаКода и МинимальнаяВысотаКода, которые автоматически рассчитались компонентой под переданную длину строки.
  4. Присваиваем свойствам Ширина и Высота компоненты эти считанные минимальные значения.
  5. Вызываем метод генерации картинки. На выходе получаем «плотный» файл штрихкода без полей.
  6. В макете табличного документа для рисунка устанавливаем свойство РазмерКартинки = Пропорционально. Платформа 1С сама красиво растянет полученное изображение на всю физическую ширину и высоту ячейки макета при выводе на печать.

Посмотрим на программную реализацию этого обходного пути:


Если ПодключитьВнешнююКомпоненту("ОбщийМакет.КомпонентаПечатиQRКода", "QR") Тогда
    QRCodeGenerator = Новый("AddIn.QR.QRCodeExtension");
    
    // Передаем кодируемые данные
    QRCodeGenerator.Текст = ПолеВводаДанных;
    
    // Получаем точный размер значащей части кода без пустых полей
    МинимальнаяШирина = QRCodeGenerator.МинимальнаяШиринаКода;
    МинимальнаяВысота = QRCodeGenerator.МинимальнаяВысотаКода;
    
    // Переопределяем параметры генерации под минимальный размер
    QRCodeGenerator.Ширина = МинимальнаяШирина;
    QRCodeGenerator.Высота = МинимальнаяВысота;
    
    // Генерируем изображение
    ДанныеИзображения = QRCodeGenerator.ПолучитьШтрихкод();
    Если ДанныеИзображения <> Неопределено Тогда
        КартинкаШК = Новый Картинка(ДанныеИзображения);
        // Выводим КартинкаШК в печатную форму
КонецЕсли;

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

Рекомендации по оформлению областей штрихкодов в макетах

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

Мы подробно проанализировали причины сбоя при формировании QR-кодов компонентой печати 1С и разобрали два эффективных программных решения. Применение этих подходов позволит вам создавать качественные, легко читаемые печатные формы с двумерными штрихкодами в любых конфигурациях 1С.

← На главную