При разработке и настройке торговых решений на платформе 1С:Предприятие разработчики часто сталкиваются с необходимостью вывода штрихкодов на печать. Стандартным инструментом для этого является компонента «1С:Печать штрихкодов» (Native API), поставляемая в составе Библиотеки стандартных подсистем (БСП) или Библиотеки подключаемого оборудования (БПО). Однако при стандартном подходе к выводу штрихкода подпись под ним (цифры или символы кода) очень часто отображается крайне некачественно: шрифт выглядит рваным, размытым, пикселизированным или «грязным». Это не только портит визуальный вид этикетки или документа, но и может приводить к проблемам со считыванием штрихкода сканером.
В этой статье мы подробно разберем природу данной проблемы, выясним, почему стандартный механизм рендеринга дает такой сбой, и рассмотрим несколько эффективных способов решения — от простых «лайфхаков» с масштабированием до профессиональных методов разделения слоев печати и использования векторной графики.
Прежде чем перейти к исправлению кода, давайте проанализируем, почему стандартная компонента Native API выдает «кривой» шрифт. Причины кроются во внутренних механизмах работы платформы 1С и самой компоненты:
Выяснив причину дефекта, рассмотрим рабочие варианты его устранения.
Рассмотрим самый быстрый программный способ, который позволяет исправить ситуацию без изменения структуры макета табличного документа. Суть метода заключается в обмане механизма рендеринга компоненты: мы заставляем её генерировать картинку в огромном разрешении (например, в 10 раз больше требуемого), а затем средствами платформы 1С сжимаем ее до размеров области макета с включенным свойством пропорционального сжатия.
При таком подходе компонента прорисовывает шрифт на большой пиксельной сетке, где он получается идеально гладким и четким. При последующем сжатии картинки в табличном документе платформа 1С применяет собственные качественные алгоритмы интерполяции, сохраняя четкость текста и штрихов.
Разберем реализацию этого метода по шагам на примере кода:
Процедура ЗаполнитьРисунокШтрихкодомМасштабирование(Рисунок, ШтрихКод, ТипКода = Неопределено)
// Определяем коэффициенты пересчета пикселей в миллиметры на основе эталонного макета
Эталон = ПолучитьОбщийМакет("МакетДляОпределенияКоэффициентовЕдиницИзмерения");
КоличествоМиллиметровВПикселеВысота = Эталон.Рисунки.Квадрат100Пикселей.Высота / 100;
КоличествоМиллиметровВПикселеШирина = Эталон.Рисунки.Квадрат100Пикселей.Ширина / 100;
// Вычисляем базовый размер штрихкода в пикселях под размер рисунка на макете
БазоваяШирина = Окр(Рисунок.Ширина / КоличествоМиллиметровВПикселеШирина);
БазоваяВысота = Окр(Рисунок.Высота / КоличествоМиллиметровВПикселеВысота);
// Вводим коэффициент масштабирования (увеличиваем разрешение в 10 раз)
КоэффициентМасштаба = 10;
ШиринаШтрихкода = БазоваяШирина * КоэффициентМасштаба;
ВысотаШтрихкода = БазоваяВысота * КоэффициентМасштаба;
// Заполняем параметры генерации штрихкода
ПараметрыШтрихкода = Новый Структура;
ПараметрыШтрихкода.Вставить("Ширина" , ШиринаШтрихкода);
ПараметрыШтрихкода.Вставить("Высота" , ВысотаШтрихкода);
ПараметрыШтрихкода.Вставить("ТипКода" , ?(ЗначениеЗаполнено(ТипКода), ТипКода, 1)); // 1 - это EAN13 по умолчанию
ПараметрыШтрихкода.Вставить("ОтображатьТекст" , Истина);
// Размер шрифта также пропорционально увеличиваем в 10 раз
ПараметрыШтрихкода.Вставить("РазмерШрифта" , 10 * КоэффициентМасштаба);
ПараметрыШтрихкода.Вставить("МонохромныйШрифт" , Ложь);
ПараметрыШтрихкода.Вставить("УголПоворота" , 0);
ПараметрыШтрихкода.Вставить("Штрихкод" , ШтрихКод);
ПараметрыШтрихкода.Вставить("ПрозрачныйФон" , Истина);
ПараметрыШтрихкода.Вставить("УровеньКоррекцииQR", 1);
ПараметрыШтрихкода.Вставить("Масштабировать" , Ложь);
ПараметрыШтрихкода.Вставить("СохранятьПропорции", Ложь);
ПараметрыШтрихкода.Вставить("ВертикальноеВыравнивание", 3); // Выравнивание по нижнему краю
// Получаем качественную картинку высокого разрешения из компоненты БПО
Рисунок.Картинка = МенеджерОборудованияВызовСервера.ПолучитьКартинкуШтрихкода(ПараметрыШтрихкода);
// ВАЖНО: Устанавливаем режим размера картинки "Пропорционально"
// Это заставит платформу качественно сжать большую картинку под физический размер рисунка на форме/макете
Рисунок.РазмерКартинки = РазмерКартинки.Пропорционально;
КонецПроцедуры
Результат: Штрихкод генерируется с высокой плотностью пикселей, благодаря чему цифры прорисовываются без искажений геометрических пропорций. При выводе на печать линии штрихкода остаются тонкими и контрастными, а шрифт становится легко читаемым как для человека, так и для аппаратного сканера.
Несмотря на то, что метод масштабирования отлично справляется с задачей улучшения картинки, у него остается концептуальный минус: текст под штрихкодом все равно выводится в виде растрового изображения. При печати на термотрансферных принтерах этикеток с низким разрешением (например, 203 DPI) даже масштабированный растровый текст может слегка подплывать.
Наиболее надежным, профессиональным и «чистым» решением является разделение вывода штрихов кода и текстовой подписи:
ОтображатьТекст (или ShowText в некоторых версиях компоненты) присваиваем значение Ложь.Рассмотрим, как меняются параметры генерации штрихкода при таком подходе:
ПараметрыШтрихкода = Новый Структура;
ПараметрыШтрихкода.Вставить("Ширина" , ШиринаШтрихкода);
ПараметрыШтрихкода.Вставить("Высота" , ВысотаШтрихкода);
ПараметрыШтрихкода.Вставить("ТипКода" , ТипКода);
ПараметрыШтрихкода.Вставить("ОтображатьТекст" , Ложь); // Отключаем вывод текста компонентой
ПараметрыШтрихкода.Вставить("Штрихкод" , ШтрихКод);
ПараметрыШтрихкода.Вставить("ПрозрачныйФон" , Истина);
Рисунок.Картинка = МенеджерОборудованияВызовСервера.ПолучитьКартинкуШтрихкода(ПараметрыШтрихкода);
В макете табличного документа под рисунком штрихкода объединяем ячейки, задаем для них качественный системный векторный шрифт платформы (например, Arial или Tahoma), устанавливаем нужный размер (например, 9pt) и центрирование. При выводе области макета заполняем текстовый параметр значением штрихкода.
Преимущества метода:
Часто проблема «корявого» или «дефолтного» шрифта компоненты обостряется при переносе базы 1С на сервер под управлением Linux (например, CentOS, Ubuntu или Debian). Стандартная компонента Native API при формировании картинки пытается найти в системе качественные шрифты (по умолчанию она ищет шрифт Arial или Tahoma). Если эти шрифты отсутствуют в системе, компонента без предупреждения переключается на самый примитивный растровый шрифт, доступный в ядре ОС, что приводит к ужасному качеству отображения.
Чтобы решить эту проблему на серверах Linux, выполним следующие шаги:
yum install msttcore-fonts-installer, для Debian/Ubuntu — apt-get install ttf-mscorefonts-installer.
// Пример программного обхода доступных шрифтов компоненты
Если КомпонентаПечати.НайтиШрифт("Arial") Тогда
ПараметрыШтрихкода.Вставить("Шрифт", "Arial");
ИначеЕсли КомпонентаПечати.КоличествоШрифтов > 0 Тогда
// Если Arial не найден, принудительно берем первый доступный качественный векторный шрифт системы
ПервыйДоступныйШрифт = КомпонентаПечати.ШрифтПоИндексу(0);
ПараметрыШтрихкода.Вставить("Шрифт", ПервыйДоступныйШрифт);
КонецЕсли;
Если вы хотите полностью отказаться от внешних компонент генерации картинок (которые могут нестабильно инициализироваться в разных режимах работы платформы, например, на x64-серверах или в веб-клиенте), можно использовать альтернативный метод — специализированные TrueType-шрифты штрихкодов.
Суть метода заключается в следующем:
EanGnivc для штрихкодов EAN или IDAutomation). Этот шрифт сопоставляет цифрам и специальным символам графические изображения штрихов.Посмотрим на пример функции подготовки строки для шрифта EanGnivc:
Функция СформироватьСтрокуДляШрифтаEAN13(Знач ИсходныйШтрихкод) Экспорт
// Алгоритм преобразует 13 цифр EAN-13 в специальный набор символов,
// учитывая левую и правую части кода, а также контрольный символ
// Для каждого типа шрифта используется своя спецификация кодирования.
Если СтрДлина(ИсходныйШтрихкод) <> 13 Тогда
Возврат ИсходныйШтрихкод;
КонецЕсли;
// Кодирование первой цифры
Результат = Сред(ИсходныйШтрихкод, 1, 1);
// Логика формирования символов для левой части (символы 2-7) и правой части (символы 8-13)
// ...
// В данном примере опускаем полную математическую реализацию расчета контрольного числа
Возврат Результат;
КонецФункции
При таком подходе и штрихкод, и текст под ним являются 100% векторными текстовыми объектами платформы 1С. Они масштабируются абсолютно без потери качества, весят ничтожно мало и печатаются идеально четко на любом принтере с любым разрешением DPI.
Мы подробно проанализировали причины деградации качества шрифтов при выводе штрихкодов стандартной компонентой 1С и изучили практические способы решения этой проблемы.
Для быстрого исправления «здесь и сейчас» рекомендуем применить Способ 1 (масштабирование картинки в 10 раз с пропорциональным сжатием). Он требует изменения всего нескольких строк кода в процедуре формирования рисунка штрихкода.
Если же вы разрабатываете тиражное решение или стремитесь к максимальному качеству печати на специализированных принтерах этикеток, лучшим выбором будет Способ 2 (разделение вывода штрихов и текста подписи). Этот вариант гарантирует безупречную четкость шрифта и исключает любые проблемы со считыванием кодов на кассовых узлах и складах.