Распознавание штрихкодов со сканированных документов в формате PDF — это распространенная задача в автоматизации складского учета и документооборота. В отличие от обычных картинок (JPG, PNG), PDF-файл является контейнером, который 1С или специализированные библиотеки распознавания не всегда могут прочитать напрямую. В этой статье мы подробно разберем, как построить надежную цепочку обработки: от конвертации PDF в изображение до получения значения штрихкода.
Разберем ситуацию, когда при попытке конвертации через команду magick convert возникает "Ошибка 1". Чаще всего это происходит из-за того, что ImageMagick сам по себе не умеет интерпретировать язык описания страниц PostScript и PDF. Для этих целей он использует внешний "движок" — Ghostscript.
Проанализируем ключевые требования для работы связки:
ImageMagick, то и Ghostscript должен быть строго 64-битным. В противном случае библиотеки не увидят друг друга.Ghostscript должен быть правильно установлен, чтобы ImageMagick мог найти его через системный реестр или переменную окружения PATH.Рассмотрим, как правильно сформировать команду для получения качественного изображения, которое библиотека распознавания сможет обработать без ошибок. Выясним причину, почему стандартные настройки могут не подходить для штрихкодов.
Для качественного распознавания плотность пикселей (DPI) должна быть не менее 300. Команда для запуска из 1С должна выглядеть следующим образом:
Команда = """C:\Program Files\ImageMagick-7.1.1-Q16-HDRI\magick.exe"" -density 300 ""C:\Temp\src.pdf"" -strip -quality 100 ""C:\Temp\res.png""";
ЗапуститьПриложение(Команда, , Истина, КодВозврата);
Обратите внимание на синтаксис 7-й версии ImageMagick: рекомендуется использовать просто magick, а параметры обработки (например, -density) указывать до входного файла. Это позволяет программе сначала задать параметры рендеринга PDF, а затем уже читать сам файл.
Если PDF-файл создан сканером, то внутри него, скорее всего, уже лежит готовое изображение. Вместо того чтобы перерисовывать (рендерить) страницу заново с помощью тяжелого Ghostscript, мы можем просто "вынуть" оригинальную картинку. Для этого идеально подходит утилита pdfimages из пакета Poppler.
Посмотрим на пример команды:
// Извлекает все изображения из PDF в формате PNG
Команда = "pdfimages -png C:\Temp\src.pdf C:\Temp\extracted_image";
ЗапуститьПриложение(Команда, , Истина);
Этот способ работает значительно быстрее и не требует установки громоздких библиотек, так как pdfimages может работать в портативном (portable) режиме.
После того как мы получили файл res.png, нам нужно извлечь из него текстовое значение штрихкода. Одной из самых надежных бесплатных библиотек для этого является ZBar. Рассмотрим, как интегрировать её в 1С.
Проанализируем процесс вызова утилиты zbarimg:
ПутьКZBar = "C:\Program Files (x86)\ZBar\bin\zbarimg.exe";
ПутьККартинке = "C:\Temp\res.png";
// Флаг --raw позволяет получить только значение штрихкода без лишней информации
Команда = """" + ПутьКZBar + """ --raw -q """ + ПутьККартинке + """";
// Используем запуск с перенаправлением вывода, чтобы получить результат
ТекстРезультата = "";
ЗапуститьПриложение(Команда, , Истина, КодВозврата);
// В реальной задаче лучше использовать чтение через файл или поток
Важный совет: чтобы повысить точность распознавания, перед подачей картинки в ZBar, её можно предварительно обработать в ImageMagick, переведя в черно-белый формат (бинаризация):
// Добавляем контраст и убираем цвета
КомандаОбработки = "magick convert res.png -colorspace gray -threshold 50% res_optimized.png";
Рассмотрим пример функции, которая объединяет все шаги: конвертацию и распознавание. Мы будем использовать временные файлы, чтобы не оставлять мусора на диске.
Функция РаспознатьШтрихкодИзPDF(ПутьКФайлуPDF) Экспорт
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("png");
ПутьКMagick = "C:\Program Files\ImageMagick-7.1.1-Q16-HDRI\magick.exe";
ПутьКZBar = "C:\ZBar\bin\zbarimg.exe";
// 1. Конвертация PDF в PNG
ПараметрыIM = СтрШаблон("-density 300 ""%1"" -background white -alpha remove -strip ""%2""", ПутьКФайлуPDF, ИмяВременногоФайла);
КомандаIM = """" + ПутьКMagick + """ " + ПараметрыIM;
КодВозврата = 0;
ЗапуститьПриложение(КомандаIM, , Истина, КодВозврата);
Если КодВозврата <> 0 Тогда
ЗаписьЖурналаРегистрации("ImageMagick", УровеньЖурналаРегистрации.Ошибка, , , "Ошибка конвертации PDF");
Возврат Неопределено;
КонецЕсли;
// 2. Распознавание через ZBar
// Выводим результат в текстовый файл, чтобы прочитать его в 1С
ФайлРезультата = ПолучитьИмяВременногоФайла("txt");
КомандаZBar = СтрШаблон("""%1"" --raw -q ""%2"" > ""%3""", ПутьКZBar, ИмяВременногоФайла, ФайлРезультата);
// Запускаем через cmd, чтобы сработало перенаправление потока в файл
ЗапуститьПриложение("cmd /c " + КомандаZBar, , Истина, КодВозврата);
Штрихкод = "";
Если КодВозврата = 0 Тогда
ЧтениеТекста = Новый ЧтениеТекста(ФайлРезультата, КодировкаТекста.UTF8);
Штрихкод = СокрЛП(ЧтениеТекста.Прочитать());
ЧтениеТекста.Закрыть();
КонецЕсли;
// Удаляем временные файлы
Попытка
УдалитьФайлы(ИмяВременногоФайла);
УдалитьФайлы(ФайлРезультата);
Исключение
КонецПопытки;
Возврат Штрихкод;
КонецФункции
Для успешного решения задачи нам потребовалось:
-density 300 для обеспечения высокой четкости штрихкода при рендеринге.1С через метод ЗапуститьПриложение с ожиданием завершения.Если ваша система предполагает высокую нагрузку (сотни документов в минуту), рассмотрите возможность использования Native API компонентов для 1С, которые работают с библиотеками ZXing или OpenCV напрямую, без вызова внешних исполняемых файлов. Это избавит от накладных расходов на создание процессов в операционной системе и запись временных файлов.