img2pdf объединяет JPEG, PNG, TIFF, GIF, JPEG 2000, MPO и другие растровые изображения в одно- или многостраничный PDF, сохраняет исходные пиксели без повторного сжатия там, где формат PDF допускает прямое вложение, и позволяет точно задать размер страницы, поля, поворот, метаданные, PDF/A и параметры открытия документа.
Основной рабочий процесс строится вокруг одной команды: перечислите изображения в нужном порядке, укажите файл результата через -o, а затем при необходимости добавьте геометрию страницы, способ вписывания и служебные свойства PDF. Каждый входной файл либо кадр многостраничного изображения становится отдельной страницей; поэтому порядок аргументов сразу определяет последовательность листов.
У программы нет монтажного поля с миниатюрами, инструментов ретуши и ручного перетаскивания страниц. Зато её параметры однозначны и воспроизводимы: одну и ту же команду можно повторить для сотен папок, встроить в сценарий сканирования или вызвать из Python, получая документ с теми же размерами, полями, метаданными и правилами поворота.
Скачать img2pdf
- Редактирование PDF
- Русский интерфейс
- Просто новичкам
- Нет визуального редактора
- Нет OCR и текстового слоя
- Параметры задаются в CLI
Как собрать первый PDF

Для простого документа достаточно перейти в каталог с изображениями и выполнить img2pdf page-001.jpg page-002.jpg -o result.pdf. Расширение выходного файла не определяет режим обработки: программа всегда формирует PDF, а ключ -o лишь направляет двоичный поток в заданный файл. Если ключ не указан, данные поступают в стандартный вывод; печатать их в терминал нельзя, зато можно перенаправить знаком >.
Перед запуском полезно привести имена к сортируемому виду: 001.jpg, 002.jpg, 010.jpg. Маска *.jpg раскрывается оболочкой, а порядок раскрытия зависит от её правил и локали. Для критичного архива безопаснее сформировать список отдельно, проверить его и только потом передать программе. На Windows поддерживаются шаблоны путей, но кавычки вокруг каталога с пробелами всё равно обязательны.
Успешная конвертация обычно не сопровождается длинным отчётом. Проверяйте код завершения, существование результата и число страниц. Ключ -v включает диагностические сообщения в стандартном потоке ошибок; это удобно в журнале пакетной обработки, поскольку сам PDF при выводе в stdout не смешивается с текстовыми сообщениями.
img2pdf page-001.jpg page-002.jpg page-003.jpg -o document.pdf
img2pdf *.png > document.pdf
img2pdf -v scans/*.jpg -o scans.pdf
Командная справка и группы параметров

Ключ --help показывает полную синтаксическую схему. Параметры разбиты на общие настройки результата, геометрию, метаданные и подсказки для PDF-просмотрщика. Короткие варианты чувствительны к регистру: -S означает размер страницы, а -s — размер изображения на странице. Такая пара легко перепутывается, поэтому в автоматических сценариях разумно использовать длинные имена --pagesize и --imgsize.
Длинное имя разрешено сокращать до однозначного префикса, однако это ухудшает читаемость и может стать неоднозначным после появления нового параметра. Для повторяемых заданий лучше записывать полные ключи. Порядок опций несущественен, а позиционные аргументы трактуются как входные изображения. Разделитель -- завершает разбор опций и позволяет передать имя, начинающееся с дефиса.
Значение, которое само начинается с дефиса, присоединяют знаком равенства: --author=--test--. В имени файла можно использовать явный относительный путь, например ./--scan.jpg. Эти приёмы устраняют двусмысленность для argparse и особенно важны в заданиях, где имена поступают извне.
Почему JPEG и часть PNG не пересжимаются
Главная особенность img2pdf — отделение упаковки изображения в контейнер PDF от повторного кодирования пикселей. JPEG и JPEG 2000 могут быть помещены в поток PDF напрямую. Для обычного нечересстрочного PNG без прозрачности программа также способна перенести сжатые данные без восстановления полного растра. В результате исходная визуальная информация не проходит ещё один цикл JPEG, не получает новые артефакты и не зависит от произвольно выбранного качества.
Прямое вложение означает, что размер результата складывается преимущественно из объёма исходных изображений и служебной структуры PDF. Для одного JPEG накладные расходы обычно невелики; у многостраничного документа добавляются объекты страниц, таблица ссылок, словари ресурсов и метаданные. Это не обещание, что любой вход даст минимальный файл: формат, прозрачность, цветовая модель и многокадровость могут потребовать преобразования.
Отсутствие повторного сжатия не улучшает исходник. Если фотография уже содержит блоки JPEG, цветовой шум или размытие, PDF сохранит их. Для уменьшения размера нужно заранее подготовить изображения подходящим редактором либо сканером: выбрать разрешение, кадрирование, цветность и качество JPEG, а img2pdf использовать как финальный сборщик. Внутри самой команды нет ползунка качества, поскольку её задача — не ретушь и не перекодирование.
Проверить прямое сохранение можно утилитой pdfimages: извлечь встроенное изображение и сопоставить его с оригиналом. Для JPEG сравнивают байты или декодированные пиксели, учитывая возможную нормализацию служебных маркеров инструментом извлечения. Важный критерий — отсутствие отличий в пикселях, а не совпадение размера каждого внешнего файла до байта.
Как обрабатываются TIFF, GIF, MPO и другие форматы
Форматы, которые нельзя вложить в PDF исходным способом, читаются через Pillow и перекодируются без потерь в представление, допустимое для PDF. Для большинства цветных растров применяется фильтрация по схеме PNG Paeth с последующим flate-сжатием. Однобитные изображения могут быть упакованы CCITT Group 4, а CMYK — flate без предварительного PNG-фильтра. Поэтому PNG с палитрой, WebP, BMP или необычный TIFF могут дать результат больше исходника, хотя пиксели сохранятся.
Однобитный скан текста особенно выгоден при корректной подготовке: CCITT Group 4 хорошо сжимает чёрно-белые страницы с большими однородными областями. Если тот же лист заранее сохранить как 24-битный RGB, программа не сможет угадать, что ему подходит бинаризация, и документ получится тяжелее. Выбор порога, очистка фона и удаление шумов должны выполняться до сборки PDF.
TIFF с уже закодированными данными CCITT Group 4 может быть встроен напрямую при совместимой структуре. Многостраничный TIFF разбирается по кадрам. TIFF с альфа-каналом поддерживается, но прозрачность потребует отдельной маски и может увеличить структуру. Для файлов с несколькими полосами, нестандартными тегами или повреждёнными смещениями возможна ошибка чтения; сначала пересохраните такой TIFF надёжным графическим инструментом.
JBIG2 принимается в варианте одностраничного generic coding. Этот формат эффективен для бинарных сканов, однако lossy-режимы некоторых кодировщиков способны подменять похожие символы. img2pdf не создаёт JBIG2 сам и не контролирует решение внешнего кодировщика, поэтому архивные документы следует готовить в без потерь режиме и проверять визуально.
Многостраничные изображения и правило кадр — страница
По умолчанию каждый кадр многостраничного TIFF или анимированного GIF превращается в отдельную страницу. Это удобно для факсов и сканов, но неожиданно для GIF, где последующие кадры содержат только изменения относительно предыдущего. Pillow собирает отображаемые кадры, а программа упаковывает получившиеся изображения; объём может значительно превысить размер анимации.
Ключ --first-frame-only оставляет только первый кадр каждого многокадрового файла. Он нужен, когда TIFF используется как контейнер с превью либо GIF служит иллюстрацией, а не последовательностью страниц. Ключ действует на каждый вход отдельно: при списке из трёх GIF в PDF окажутся три первые рамки.
MPO часто содержит основное фото и уменьшенные или стереоскопические кадры. По умолчанию дополнительные миниатюры не выводятся отдельными страницами. Параметр --include-thumbnails меняет это поведение и включает каждый кадр. Перед пакетной обработкой MPO рекомендуется проверить один образец: число страниц покажет, какие изображения реально присутствуют в контейнере.
Порядок кадров внутри одного файла задаётся самим контейнером, затем следует следующий позиционный аргумент. Переставить отдельные кадры во время конвертации нельзя. Для произвольной композиции сначала извлеките кадры в отдельные файлы и сформируйте явный список.
Размер страницы и размер изображения

Геометрию задают два независимых понятия. --pagesize определяет MediaBox страницы PDF, то есть физический лист. --imgsize определяет прямоугольник, который занимает изображение на этом листе. Если ничего не задано, физический размер выводится из количества пикселей и DPI, записанного в изображении; при отсутствующих или непригодных данных используется базовое значение 96 dpi.
Размер записывается как ширина и высота через латинскую x: 210mmx297mm, 8.5inx11in или 595ptx842pt. Разрешены единицы pt, cm, mm и in. Пробел между числом и единицей ставить нельзя. Если указана только одна сторона, вторая вычисляется с сохранением пропорций изображения.
Для --imgsize дополнительно разрешены dpi и проценты. Запись 300dpi означает рассчитать физический размер так, будто вход напечатан с плотностью 300 точек на дюйм. Процент изменяет занимаемую область относительно естественного размера. Это не ресэмплинг: число пикселей остаётся прежним, меняется масштаб изображения на странице.
Когда задана только страница, программа выводит доступную область для изображения с учётом полей. Когда задан только размер изображения и поля, размер листа строится вокруг него. Если одновременно заданы и лист, и изображение, --border не участвует в расчёте: положение всё равно центрируется, а свободное пространство получается из разницы размеров.
Стандартные форматы бумаги
Вместо чисел можно использовать имена A0–A6, B0–B6, JB0–JB6, Letter, Legal и Tabloid. Имена не зависят от регистра. Постфикс ^T меняет местами ширину и высоту, превращая портретный формат в альбомный. В cmd.exe символ каретки служит экранированием, поэтому значение вроде "A4^T" берут в кавычки.
A4 соответствует 210 × 297 мм, Letter — 8,5 × 11 дюймов, Legal — 8,5 × 14 дюймов, Tabloid — 11 × 17 дюймов. Серии B и JB отличаются размерами; выбор только по букве без проверки может привести к неверному полю при печати. Для типографии лучше согласовать точный MediaBox и не полагаться на автоматическое масштабирование драйвера.
Размер страницы не меняет ориентацию пикселей. Если портретное фото помещается на альбомный лист, оно останется портретным и получит широкие поля по бокам, если не включён другой способ вписывания. Для смешанного набора используйте --auto-orient или разделите источники по ориентации.
Пять способов вписывания изображения

Ключ --fit принимает into, fill, exact, shrink и enlarge. Режим into выбран по умолчанию: изображение целиком помещается в заданный прямоугольник, пропорции сохраняются, свободное место остаётся полями. Это безопасный вариант для страниц разной формы.
fill масштабирует с сохранением пропорций так, чтобы прямоугольник был заполнен по обеим сторонам. Часть изображения выходит за рамку целевой области. Поскольку img2pdf не является редактором кадрирования, пользователь должен заранее понимать, какая область окажется за границей страницы или видимой рамки.
exact жёстко задаёт обе стороны и не сохраняет отношение ширины к высоте. Круг может стать эллипсом, а текст — растянутым. Этот режим оправдан только при заранее нормализованных источниках либо когда искажение действительно требуется техническим процессом.
shrink ведёт себя как into только для изображений, которые больше рамки; маленькие не увеличиваются. enlarge, наоборот, увеличивает слишком маленькие и оставляет крупные в естественном масштабе, если они уже превышают цель. Оба режима сохраняют пропорции.
img2pdf *.jpg -o into.pdf --pagesize A4 --fit into
img2pdf *.jpg -o fill.pdf --pagesize A4 --fit fill
img2pdf *.jpg -o shrink.pdf --pagesize A4 --imgsize 10cmx15cm --fit shrink
Поля и центрирование
Параметр --border задаёт минимальное расстояние между изображением и краем страницы. Одно значение применяется ко всем сторонам, два значения через двоеточие означают вертикальное и горизонтальное поле: 2cm:2.5cm. Асимметричные поля не поддерживаются, потому что изображение всегда центрируется.
Поле участвует в вычислении только тогда, когда одна из геометрий выводится из другой. Если явно задать и --pagesize, и --imgsize, программа игнорирует --border; фактические отступы определяются свободным пространством после центрирования. Это важно при попытке получить точный корешковый отступ: сместить изображение вправо или влево одной опцией нельзя.
Для двусторонней печати с внутренним полем придётся подготовить разные страницы внешним инструментом либо добавить прозрачное пространство в сам растр. img2pdf не чередует левую и правую координату и не знает понятия зеркальных полей. Зато одинаковые поля воспроизводятся строго и удобны для фотопечати, карточек и стандартных листов.
MediaBox, CropBox, BleedBox, TrimBox и ArtBox
Кроме обычного края страницы программа умеет задавать четыре дополнительные рамки PDF: --crop-border, --bleed-border, --trim-border и --art-border. Значение описывает расстояние соответствующего бокса от MediaBox. Как и обычные поля, допускаются одно значение для всех сторон или пара верх/низ:лево/право.
CropBox определяет область, которую многие просмотрщики показывают и печатают по умолчанию. TrimBox обозначает предполагаемый обрезной формат, BleedBox — область выпуска под обрез, ArtBox — значимую художественную область. Само изображение не дорисовывается за пределами исходных пикселей: рамки лишь записывают координаты в структуру PDF.
Значение не может быть больше половины соответствующей стороны страницы; иначе рамка станет отрицательной или вывернутой, и программа завершит работу с ошибкой. Для типографского задания сначала рассчитайте MediaBox с выпуском, затем задайте TrimBox как отступ от него. После создания проверьте все боксы через pdfinfo -box или допечатный анализатор.
Автоматическая ориентация страницы

--auto-orient сравнивает ориентацию каждого изображения с ориентацией страницы, заданной обеими сторонами. Если они не совпадают, ширина и высота листа меняются местами. При этом пара полей также транспонируется: вертикальный и горизонтальный отступ остаются привязаны к геометрии после поворота.
Этот режим удобен для папки, где смешаны портретные и альбомные фотографии. В одном PDF MediaBox страниц может различаться. Некоторые системы печати ожидают одинаковый размер всех листов; в таком случае автоматическую ориентацию использовать не стоит, а изображения лучше вписывать в единый A4.
Автоориентация страницы не равна EXIF-повороту. Сначала интерпретируется ориентация пикселей, затем выбирается форма листа. Если EXIF ошибочен, результат может оказаться перевёрнутым или получить неверную страницу. Для проблемной камеры сочетайте --rotation=ifvalid с --auto-orient.
EXIF Orientation и принудительный поворот

Параметр --rotation, также доступный как --orientation, принимает auto, none, ifvalid, 0, 90, 180 и 270. По умолчанию действует auto: программа читает EXIF Orientation и задаёт правильное отображение. Значения 90, 180 и 270 означают поворот по часовой стрелке.
none и 0 игнорируют EXIF. Это полезно, если пиксели уже физически повёрнуты, а старый тег остался в файле. ifvalid применяет допустимые значения, но не прекращает пакет при некорректном теге. Вместо этого выводится предупреждение, и проблемный кадр обрабатывается без аварии.
Некоторые телефоны, камеры и сканеры записывают нулевой Orientation, хотя стандарт допускает другие значения. Строгий режим считает файл повреждённым. Для архива лучше сначала исправить метаданные с помощью exiftool и сохранить однозначный исходник. ifvalid полезен как оперативная мера, но после сборки нужно просмотреть страницы, потому что проигнорированный тег не сообщает, как кадр следовало повернуть.
Поворот задаётся средствами PDF и обработкой метаданных в зависимости от формата; задача не требует повторного JPEG-сжатия. Однако сторонний просмотрщик может учитывать матрицу и страницу иначе при экспорте. Проверяйте не только вид в одном приложении, но и печать или последующее распознавание.
DPI: физический размер без изменения пикселей
DPI связывает пиксели с физическими единицами. Изображение 3000 × 2000 пикселей при 300 dpi занимает 10 × 6,67 дюйма, а при 100 dpi — 30 × 20 дюймов. img2pdf не добавляет деталей при смене dpi и не уменьшает число пикселей; меняется только размер размещения на PDF-странице.
Ключ --imgsize 300dpi принудительно использует заданную плотность вместо метаданных. Он полезен для сканов, где программа сканера потеряла или неверно записала разрешение. Если указать чрезмерно низкое значение, страница может превысить предел PDF в 200 дюймов. Для очень большой геометрии предусмотрено разрешение oversized-страниц в программном API, но совместимость просмотрщиков всё равно нужно проверять.
Некоторые PNG содержат разные значения разрешения по горизонтали и вертикали либо аспект без единицы. Это влияет на физические пропорции. Если документ должен быть метрически точным, не полагайтесь на метаданные неизвестного происхождения: задайте dpi явно и измерьте итоговый MediaBox.
Для печати текста обычно важна эффективная плотность после вписывания. Разделите число пикселей по ширине на ширину отпечатка в дюймах. Если страница 2480 пикселей помещена на 8,27 дюйма A4, эффективное значение близко к 300 dpi. Поля уменьшают доступную ширину и повышают эффективную плотность.
Цветовые пространства и параметр --colorspace
Обычно цветовая модель определяется автоматически. Ключ --colorspace принудительно записывает RGB, L, 1, CMYK или CMYK;I. Он особенно нужен для JPEG 2000, где библиотека не всегда может вывести цветовое пространство из файла. Неверное принуждение не конвертирует содержимое осмысленно, а заставляет интерпретировать компоненты иначе, поэтому цвета могут исказиться.
RGB используется для обычных цветных изображений, L — для градаций серого, 1 обозначает чёрно-белое представление, которое внутри трактуется как градации серого. CMYK сохраняет четыре печатные компоненты. CMYK;I предназначен для инвертированных CMYK JPEG, встречающихся у файлов Adobe.
В оболочке точка с запятой разделяет команды. Значение CMYK;I обязательно заключают в кавычки либо экранируют, иначе после CMYK оболочка попытается запустить отдельную команду I. На Windows правила кавычек отличаются, но безопаснее также передавать весь аргумент единым токеном.
Принудительная модель не заменяет управление цветом. Для корректной печати важны встроенные ICC-профили и поведение получателя. img2pdf может сохранить профиль изображения там, где это уместно, и использовать отдельный профиль для PDF/A, но не выполняет художественное преобразование между профилями с выбором rendering intent.
Прозрачность и мягкая маска
Изображение с альфа-каналом нельзя вложить в PDF как обычный непрозрачный поток без дополнительной структуры. img2pdf сохраняет цветовые данные и создаёт отдельную soft mask для прозрачности. Такой путь остаётся без потерь, но итог содержит два связанных изображения и обычно больше исходного файла.
Полупрозрачные края, тени и антиалиасинг сохраняются. Фон определяется просмотрщиком или последующей композицией; при печати он часто белый. Если документ должен выглядеть одинаково в старых системах, заранее сводите изображение с требуемым фоном. Это уже изменяет пиксели, поэтому исходник следует хранить отдельно.
Чересстрочный PNG и PNG с прозрачностью не попадают в самый простой режим прямого переноса. Они декодируются и упаковываются допустимым способом. Разница в размере между двумя визуально одинаковыми PNG может быть существенной именно из-за структуры и альфа-канала, а не из-за качества результата.
Метаданные документа

Параметры --title, --author, --creator, --producer, --subject и --keywords заполняют информационный словарь PDF. Заголовок отображается в свойствах документа и иногда в заголовке окна. Creator обычно обозначает процесс, подготовивший исходное содержимое, а Producer — средство формирования PDF.
Ключевые слова передаются одним или несколькими значениями. Если фраза содержит пробелы, её берут в кавычки. Метаданные не создают закладок и не индексируют текст внутри сканов; они лишь описывают файл. Для поиска по содержимому нужен OCR и текстовый слой, которых img2pdf не добавляет.
Даты задаются через --creationdate и --moddate. Поддерживаются формы с датой и временем; интерпретация расширенных форматов может зависеть от доступного dateutil или системной команды date. В автоматическом архиве лучше использовать однозначный UTC-формат и проверять свойства после создания.
Unicode-метаданные зависят от выбранного PDF-движка. Внутренний и pikepdf подходят лучше; pdfrw имеет ограничение на Unicode. Если русское название отображается кракозябрами, переключите двигатель и пересоздайте документ, а не пытайтесь менять кодировку аргумента вслепую.
Подсказки для PDF-просмотрщика
PDF может сообщить приложению, как открыть документ. --viewer-panes thumbs просит показать миниатюры, а outlines — панель структуры. img2pdf не создаёт закладки, поэтому outlines без внешне добавленного дерева обычно мало полезен. Одновременно указать обе панели нельзя.
--viewer-initial-page задаёт начальную страницу, нумерация начинается с единицы. --viewer-magnification принимает числовой масштаб, fit для целой страницы, fith для ширины и fitbh для видимой ширины. Конкретный просмотрщик вправе проигнорировать рекомендацию или восстановить собственное состояние предыдущего сеанса.
Режим раскладки задаётся значениями single, onecolumn, twocolumnright, twocolumnleft, twopageright и twopageleft. Для сканированной книги выбор разворотов зависит от того, на какой стороне должна быть первая страница. Ошибка в right/left сдвигает пары, поэтому откройте файл в приложении, которое уважает PageLayout.
--viewer-fit-window просит подогнать окно под страницу, --viewer-center-window — центрировать его, --viewer-fullscreen — открыть в полноэкранном режиме. Эти флаги не являются защитой и не гарантируют одинаковый интерфейс у получателя.
PDF/A-1b и ICC-профиль

Ключ --pdfa формирует структуру PDF/A-1b и требует профиль ICC, описывающий цветовое пространство вывода. В командной строке можно передать путь к профилю. Без доступного подходящего файла операция завершается ошибкой либо не может гарантировать соответствие архивному стандарту.
PDF/A-1b ориентирован на воспроизводимость визуального вида, но не делает скан доступным для поиска и не подтверждает смысловую структуру. Изображения остаются изображениями. Для архивного процесса отдельно выполняют OCR, контроль ориентации, проверку полноты, присвоение метаданных и валидацию стандарта.
Путь к системному sRGB-профилю различается между дистрибутивами и операционными системами. Не копируйте пример без проверки. Укажите профиль, право на распространение которого вам известно, и сохраните его идентификатор в журнале процесса. Для печатного CMYK-архива нужен профиль, соответствующий требованиям получателя.
После создания используйте специализированный валидатор PDF/A. Обычное открытие в просмотрщике подтверждает лишь читаемость. Валидатор проверит OutputIntent, XMP, ограничения шрифтов и объектов, версию PDF и другие формальные условия. Если файл затем изменить редактором, соответствие надо проверять заново.
Выбор PDF-движка
Параметр --engine принимает internal, pikepdf или pdfrw. Внутренний двигатель не требует дополнительных модулей и записывает сравнительно читаемую структуру PDF. Для типовой упаковки изображений он достаточен и уменьшает число зависимостей.
pikepdf использует библиотеку qpdf, поддерживает больше возможностей, способен линеаризовать документ для быстрого показа по сети и сжимать больше служебных частей. Для него должны быть установлены Python-модуль pikepdf и совместимая qpdf. Ошибка импорта означает, что выбранный двигатель недоступен, даже если базовая команда img2pdf запускается.
pdfrw требует одноимённый модуль, но имеет известные ограничения: Unicode в метаданных и палитровые данные поддерживаются хуже. Его выбирают ради совместимости со старым процессом, а не как универсальный вариант. При переходе между двигателями сравните метаданные, прозрачность, палитры и поведение просмотрщика.
Двигатель влияет на структуру контейнера, но не должен превращать прямой JPEG в новый JPEG. Размер файлов может отличаться из-за таблиц, сжатия словарей и порядка объектов. Сравнивайте не только байты, но и страницы, встроенные изображения и валидность.
Стандартный ввод, стандартный вывод и конвейеры

Без входных аргументов программа читает одно изображение из stdin. Специальное имя - также обозначает стандартный ввод и может быть использовано один раз. Поскольку обработчику требуется позиционирование по данным, не каждый произвольный бесконечный поток подходит; практический пример предварительно кодирует страницу сканера в JPEG.
Без -o PDF пишется в stdout. Это позволяет передать его следующей программе, сохранить перенаправлением или отправить по защищённому каналу. Диагностика идёт в stderr, поэтому ключ -v не повреждает двоичный поток при корректном перенаправлении.
Команда scanimage --mode=Color --resolution=300 | pnmtojpeg -quality 90 | img2pdf > scan.pdf строит PDF без промежуточного файла. Качество и потери определяются стадией pnmtojpeg; img2pdf лишь упаковывает полученный JPEG. Если нужен без потерь путь, выберите другой промежуточный формат и оцените размер.
В сценарии обязательно проверяйте статус каждого звена. Обычный shell возвращает статус последней команды, поэтому ошибка сканера может остаться незамеченной. В Bash включают set -o pipefail, записывают результат во временный файл, проверяют его и затем атомарно переименовывают.
Списки из тысяч файлов и --from-file

У оболочки есть предел суммарной длины командной строки. Каталог с десятками тысяч страниц может не поместиться в *.jpg. --from-file читает пути из файла, где записи разделены нулевыми байтами. Такой разделитель корректно работает с пробелами, кавычками и переводами строк в имени.
Список нельзя смешивать с позиционными изображениями. Если передан --from-file, обычный список аргументов должен быть пуст. Значение - читает нулевой список из stdin. Типичный конвейер сочетает find -print0 и сортировку, поддерживающую нулевые разделители.
Порядок find не считается гарантированным. Для страниц создайте устойчивый ключ сортировки. Лексикографическая сортировка ставит 10 перед 2, если номера не дополнены нулями. Лучше нормализовать имена при сканировании либо сформировать список скриптом, который извлекает числовую часть.
Список следует хранить как артефакт задания: по нему легко воспроизвести PDF и найти пропущенную страницу. Перед конвертацией проверьте дубликаты, пустые файлы и пути к каталогам. Одна ошибка чтения прекращает операцию; частичный результат не следует публиковать как завершённый.
Использование img2pdf из Python

Модуль предоставляет функцию convert(). Ей можно передать пути, pathlib.Path, файловые объекты, байтовые данные, список или несколько позиционных изображений. Возвращаемые байты записывают в файл, либо используют outputstream, чтобы выводить непосредственно в открытый двоичный поток.
Простейший вариант: f.write(img2pdf.convert("page.jpg")). Для нескольких страниц передайте несколько путей или список. Не открывайте изображение как текст: файловый объект должен читать bytes. Выходной файл также открывается с режимом wb, иначе Python попытается трактовать PDF как строку.
Геометрию задаёт layout function. Готовая функция может построить A4, использовать фиксированный dpi или вычислять размеры по собственному правилу. Значения задаются в пунктах PDF; вспомогательные функции переводят миллиметры и дюймы. Пользовательская функция получает ширину и высоту в пикселях и dpi, а возвращает размеры страницы и изображения.
Для PDF/A в API передаётся путь к ICC-профилю. Для повреждённого Orientation используется enum Rotation.ifvalid. При большом объёме предпочтителен outputstream: это снижает необходимость держать весь готовый PDF как единый объект bytes. Исключения надо перехватывать на уровне отдельного задания, сохраняя исходники и журнал.
import img2pdf
from pathlib import Path
images = sorted(Path('pages').glob('*.jpg'))
with open('book.pdf', 'wb') as output:
img2pdf.convert(*images, outputstream=output)
Работа со сканами документов
Для пачки сканов сначала решите, каким должен быть каждый исходный растр. Цветной договор можно хранить как JPEG высокого качества, чёрно-белый текст — как Group 4 TIFF, а страницу с прозрачностью обычно лучше свести с белым фоном. img2pdf не выравнивает перспективу, не удаляет фон и не обрезает край сканера.
Порядок страниц удобнее контролировать на этапе именования. Для двустороннего сканера проверьте, не получены ли обороты в обратном порядке. Если устройство выдаёт один многостраничный TIFF, программа разложит кадры автоматически; если нужны исключения или перестановки, сначала извлеките кадры.
Задайте физический размер. Для стандартного скана A4 можно оставить корректный dpi исходника либо принудительно поставить A4 как страницу и вписать изображение. Второй путь нормализует MediaBox, но может оставить поля из-за небольшого различия пропорций. Не используйте fill, если нельзя обрезать подписи у края.
После сборки откройте начало, середину и конец, затем проверьте число страниц. Для юридически значимого архива нужен полный постраничный контроль, OCR отдельным инструментом, проверка PDF/A и хеширование результата. img2pdf решает только этап формирования контейнера.
Фотоальбом и подготовка к печати
Для фотографий важны формат бумаги, соотношение сторон и запрет случайного увеличения маленьких кадров. Комбинация --pagesize 15cmx10cm --auto-orient подходит для бумаги 10 × 15 см, а --fit into сохранит весь кадр с возможными белыми полосами. Режим fill заполнит лист, но обрежет часть изображения.
Если лаборатория требует выпуск, одного PDF-бокса недостаточно: изображение должно реально содержать пиксели за линией реза. Подготовьте кадр с нужным припуском, затем используйте MediaBox и TrimBox по техусловиям. img2pdf не дорисовывает края и не выполняет content-aware fill.
Проверьте цветовую модель. Многие фотолаборатории ожидают sRGB JPEG; CMYK может интерпретироваться неожиданно. Программа не корректирует яркость и профиль под устройство. Все цветовые преобразования выполняйте до упаковки, а исходные файлы не удаляйте.
Для контактного листа img2pdf не размещает несколько разных изображений на одной странице. Один входной кадр соответствует одной странице. Сетку миниатюр сначала создают графическим инструментом, а уже готовые листы объединяют в PDF.
Сборка сканированной книги
Книга обычно требует одинакового размера страниц, правильных разворотов и предсказуемого режима просмотра. Нормализуйте кадры до общей геометрии, добавьте недостающие пустые листы как отдельные изображения и назовите страницы с ведущими нулями. Затем задайте A4, A5 или собственный размер и используйте into.
Для отображения разворотами применяют twopageright или twopageleft. Выбор зависит от того, является ли первая страница обложкой, правой титульной или левой. Если пары смещены, добавьте пустую страницу в начало либо измените layout; параметр не переставляет содержимое.
Панель миниатюр помогает навигации, но не заменяет оглавление. Закладки нужно добавить отдельным инструментом после сборки. Любое последующее изменение может переписать изображения, поэтому настройте редактор на сохранение встроенных потоков без лишнего пересжатия и проверьте результат через pdfimages.
Для поиска понадобится OCR. Можно сначала собрать PDF и распознать его OCRmyPDF или Tesseract, либо распознать страницы до сборки. Первый путь удобнее для единого документа, но размер и совместимость зависят от выбранного OCR-процесса.
Детерминированный результат и --nodate
По умолчанию PDF может содержать время создания, из-за чего два запуска с одинаковыми изображениями дают разные хеши. --nodate подавляет автоматически добавляемые временные метки. Это полезно для воспроизводимых сборок, кэша и контроля изменений.
Детерминизм требует большего, чем один ключ. Порядок входов должен быть одинаковым, метаданные — фиксированными, двигатель и зависимости — стабильными. Разные двигатели могут расположить объекты иначе. Также проверьте, не содержит ли источник изменяемые метаданные, влияющие на результат.
Если дата нужна по правилам архива, задайте --creationdate и --moddate явно, а не используйте время запуска. Сохраняйте часовой пояс и формат в спецификации процесса. Хеш PDF следует вычислять после всех стадий, включая OCR, подпись и оптимизацию.
Производительность и потребление памяти
Прямое копирование JPEG, JPEG 2000, подходящего PNG, Group 4 TIFF и JBIG2 экономит процессорное время: не требуется декодировать каждый пиксель и снова кодировать изображение. Это особенно заметно на больших фотографиях и сканах, где обычный конвертер создаёт полный растр в памяти.
Форматы, требующие преобразования через Pillow, потребляют память пропорционально размеру декодированного изображения, а не сжатого файла. PNG в несколько мегабайт может развернуться в сотни мегабайт. Пакет из многих страниц обрабатывается последовательно, но отдельный огромный кадр всё равно способен превысить лимит.
Pillow защищается от decompression bomb и предупреждает или блокирует изображения с чрезмерным числом пикселей. Ключ --pillow-limit-break отключает предел. Используйте его только для доверенного файла после оценки размеров: отключение защиты на неизвестных загрузках создаёт риск отказа в обслуживании.
Параллельный запуск нескольких процессов ускоряет независимые документы, но суммирует память и дисковую нагрузку. Ограничьте число рабочих процессов, особенно для TIFF, WebP и прозрачного PNG. Для прямых JPEG узким местом часто становится чтение и запись диска.
Проверка готового PDF
Первый контроль — код возврата и ненулевой размер. Затем получите число страниц и MediaBox через pdfinfo. Для смешанной ориентации проверьте несколько страниц с ключом -f/-l. При типографской подготовке выведите CropBox, BleedBox, TrimBox и ArtBox.
Второй контроль — встроенные изображения. pdfimages -list показывает формат, размеры, цветовую модель, число компонентов и наличие маски. Для JPEG можно извлечь поток и сравнить его с исходником. Если вместо ожидаемого JPEG появился flate, разберитесь, было ли это вызвано форматом, прозрачностью или последующим редактором.
Третий контроль — визуальный. Проверьте тонкие линии, мелкий текст, прозрачные края, CMYK-цвета и поворот. Разные просмотрщики могут по-разному обращаться с профилями и подсказками окна. Для целевого процесса используйте хотя бы один просмотрщик и один печатный или серверный обработчик, которые будут применяться реально.
Для PDF/A запускают валидатор, для доступности — отдельный анализатор, для OCR — поиск по нескольким словам. Наличие расширения PDF и успешное открытие не подтверждают все эти свойства.
Типичные ошибки и их устранение
Сообщение о неизвестном формате означает, что Pillow не распознал файл или не имеет нужного декодера. Убедитесь, что расширение соответствует содержимому, проверьте файл утилитой file и откройте в независимом просмотрщике. Пересохранение в PNG или TIFF часто устраняет повреждённую структуру, но может изменить метаданные.
Ошибка Orientation обычно вызвана недопустимым EXIF. Исправьте тег exiftool либо используйте --rotation=ifvalid. После обхода обязательно проверьте направление страницы. Не применяйте принудительные 90 градусов ко всей папке, если часть кадров уже правильная.
Ошибка слишком большой страницы возникает, когда физический размер превышает 200 дюймов. Причиной бывает отсутствующий dpi, неверная единица или огромный панорамный растр. Задайте разумный --imgsize, страницу и fit. Разрешать oversized следует только при известной поддержке UserUnit целевыми системами.
Ошибка о недоступном engine исправляется установкой соответствующей зависимости либо выбором internal. Для pikepdf нужен qpdf; для pdfrw — модуль pdfrw. Если метаданные на русском повреждаются, не используйте pdfrw.
Некорректные поля и боксы возникают, когда отступ больше половины страницы. Пересчитайте единицы и убедитесь, что двоеточие разделяет вертикальное и горизонтальное значения. Запятая как десятичный разделитель не подходит: используйте точку.
Пустой или повреждённый результат при конвейере часто означает ошибку предыдущей команды. Включите pipefail, пишите во временный файл и проверяйте stderr. Не перенаправляйте диагностический поток в тот же PDF.
Особенности команд в Windows
В PowerShell и cmd.exe различаются маски, кавычки и перенаправление. Пути с пробелами заключайте в двойные кавычки. В cmd.exe каретка экранирует символы, поэтому альбомный формат пишут как --pagesize "A4^T". В PowerShell список файлов может быть безопаснее сформировать через Get-ChildItem и передать по одному из сценария.
Самодостаточный EXE позволяет выполнить базовую команду без отдельной настройки Python, но параметры и ограничения остаются теми же. При загрузке проверяйте, что файл пришёл с официальной страницы выпуска, а не из каталога с рекламным загрузчиком. Запуск из проводника без аргументов не заменяет полноценную форму настроек.
Если команда не найдена, укажите полный путь к exe либо добавьте каталог в PATH. Не помещайте программу и исходники в системный каталог, требующий административной записи. Для пакетного файла проверяйте ERRORLEVEL перед перемещением результата.
Кодировка консоли влияет на отображение русских сообщений и аргументов, но имена файлов передаются системными API. При проблеме с метаданными начните с простого ASCII-пути, выберите internal или pikepdf и проверьте, не искажает ли оболочка кавычки.
Особенности оболочек Linux и macOS
В POSIX-оболочке маска раскрывается до запуска программы. Имена с пробелами, переводами строк и ведущим дефисом требуют аккуратной передачи. Для большого или недоверенного набора используйте find -print0, сортировку с нулевым разделителем и --from-file.
Точка с запятой в CMYK;I, символ каретки в формате бумаги и знаки >/< имеют специальный смысл для shell. Всегда цитируйте сложные значения. Не копируйте знак доллара из документации: он обозначает приглашение, а не часть команды.
При установке через пакетный менеджер зависимости обновляются вместе с системой. При установке через pip лучше использовать виртуальное окружение, чтобы версия Pillow, pikepdf и других модулей была контролируемой. В серверном задании фиксируйте зависимости и запускайте тестовый набор после обновления.
На macOS путь к ICC-профилю отличается от Linux. Найдите профиль фактически, а не используйте пример из другой системы. Для автоматизации через launchd или CI задайте рабочий каталог и абсолютные пути, поскольку окружение PATH будет короче интерактивного.
Экспериментальное графическое окно

Ключ --gui открывает небольшое окно на tkinter. В нём можно выбрать изображение и сохранить PDF, но настройки интерфейса отключены: размеры, поля, метаданные, движок и другие параметры недоступны как полноценные элементы управления. Поэтому окно подходит лишь для простейшего преобразования.
Кнопка Open Image выбирает вход, Save PDF — место результата. Секции Output Options, Image size и Page size показывают направление задуманных настроек, но рассчитывать на них в рабочем процессе нельзя. Для нескольких страниц, точного порядка и печатной геометрии используйте команду.
Окно не показывает монтажную ленту, предпросмотр страницы, обрезку и поворот мышью. Ошибку входа всё равно придётся диагностировать по сообщениям. Пользователю, которому важна визуальная сборка и редактирование, удобнее выбрать PDF-редактор или специализированный фотоконвертер.
Сравнение img2pdf с аналогами
img2pdf выбирают, когда изображения уже подготовлены и важны без потерь, небольшой контейнер и воспроизводимая команда. PDF Commander удобнее, когда нужно видеть страницы, вручную менять документ и работать без синтаксиса CLI. ImageMagick полезен перед сборкой: он кадрирует, меняет размер и цвет, но его PDF-путь не всегда сохраняет исходный JPEG-поток.
Tesseract нужен для распознавания и поиска по тексту; его PDF — результат OCR-процесса, а не только контейнер для готовых кадров. Pillow подходит разработчику, которому достаточно программного сохранения и который сам строит интерфейс и правила. podofoimg2pdf ближе по идее прямого JPEG, но предоставляет меньше удобных параметров.
Практический выбор прост: подготовку пикселей выполняйте графическим обработчиком, OCR — распознавателем, ручное редактирование — PDF-редактором, а img2pdf оставляйте для финальной точной упаковки уже готовых растров. В сложном процессе эти средства не исключают, а дополняют друг друга.
| Программа | Лучше подходит для | Главное ограничение |
|---|---|---|
| img2pdf | Пакетной сборки растров в PDF без лишнего пересжатия | Нет визуального монтажа и OCR |
| PDF Commander | Ручной работы с PDF, страницами и содержимым в графическом интерфейсе | Не ориентирован на скриптовую упаковку тысяч изображений |
| ImageMagick | Предварительной обработки, изменения размера, цвета и формата | При создании PDF изображения часто перекодируются |
| Tesseract OCR | Получения PDF с распознанным текстовым слоем | Не заменяет точную компоновку и обработку всех многокадровых форматов |
| Pillow | Встраивания сохранения PDF в собственный Python-код | Нет готового полнофункционального CLI для геометрии документа |
| podofoimg2pdf | Простой командной упаковки JPEG, PNG и TIFF | Меньше настроек страниц, полей, поворота и метаданных |
Безопасность и работа с недоверенными файлами
Хотя изображения не отправляются во внешний кабинет, входной файл разбирается библиотеками декодирования. Повреждённый или специально подготовленный растр может расходовать чрезмерную память либо использовать уязвимость старой зависимости. Обновляйте Pillow и вспомогательные библиотеки, запускайте обработку с ограничениями ресурсов и не отключайте защиту от decompression bomb без необходимости.
Параметр --pillow-limit-break снимает важный барьер. На сервере, куда загружают файлы посторонние, его использовать нельзя без независимой проверки размеров и формата. Ограничьте число пикселей, объём файла, время CPU, память и число страниц до запуска конвертера.
Выходной путь не должен строиться напрямую из имени пользователя. Предотвращайте выход из рабочего каталога, перезапись системного файла и гонку символьных ссылок. Создавайте результат во временном каталоге с минимальными правами, а затем переносите после валидации.
Метаданные могут раскрывать автора, путь процесса и даты. Задавайте их осознанно и проверяйте итог. --nodate убирает автоматические временные метки, но не очищает метаданные внутри исходных изображений, если они попадают в поток или профиль. Для конфиденциального архива нужен отдельный аудит.
Практические рецепты
Для сканов без изменения пикселей используйте явный порядок и файл результата. Для печатной A4 задайте страницу и поля. Для фото 10 × 15 см включите auto-orient. Для повреждённого EXIF добавьте ifvalid. Для тысяч файлов сформируйте нулевой список. Для архива включите фиксированные метаданные, PDF/A и проверку валидатором.
Команды ниже предназначены как заготовки. Перед массовым запуском замените пути, проверьте единицы и выполните один тест. Не соединяйте несовместимые цели: например, fill сознательно допускает выход изображения за рамку, а shrink запрещает увеличение маленького кадра.
# Три страницы в заданном порядке
img2pdf 001.jpg 002.jpg 003.jpg -o document.pdf
# Альбомная A4 с полями
img2pdf *.jpg -o print.pdf --pagesize "A4^T" --border 2cm:2.5cm
# Фотобумага 10 × 15 см с автоматической ориентацией
img2pdf *.jpg -o photos.pdf --pagesize 15cmx10cm --auto-orient
# Игнорировать только некорректный EXIF-поворот
img2pdf *.jpg -o camera.pdf --rotation=ifvalid
# Список огромной папки
find pages -type f -name '*.jpg' -print0 | sort -z | img2pdf --from-file - -o book.pdf
# Воспроизводимые метаданные
img2pdf pages/*.png -o archive.pdf --nodate --title "Архив" --author "Отдел"
Контрольный список перед публикацией документа
Сверьте число исходных кадров и страниц. Убедитесь, что маска не захватила превью, обложку из другой папки или временный файл. Проверьте сортировку на переходах 9→10, 99→100 и на именах с суффиксами. Для многокадровых форматов отдельно проверьте, сколько страниц дал каждый файл.
Сопоставьте физические размеры с задачей. PDF может выглядеть нормально на экране, но печататься гигантским из-за неверного dpi. Проверьте MediaBox в пунктах или миллиметрах, ориентацию, поля и дополнительные боксы. Убедитесь, что программа печати не включает собственный режим подогнать.
Откройте страницы с прозрачностью, CMYK, JPEG 2000 и нестандартным TIFF. Сравните цвета и края в целевом просмотрщике. Для прямого JPEG извлеките изображение и подтвердите отсутствие повторного сжатия. Для PDF/A получите отчёт валидатора.
Проверьте метаданные, даты и рекомендации открытия. Они не должны содержать тестовые значения, внутренние пути или личные сведения. Если документ проходит следующую стадию — OCR, подпись, оптимизацию — повторите проверки после неё, потому что структура и изображения могут измениться.
Храните команду, список входов, журнал stderr и хеш готового файла рядом с заданием. Такой набор позволяет воспроизвести результат и объяснить различия. Сам PDF не содержит полного рецепта: по нему нельзя надёжно восстановить исходный порядок, выбранные ключи и состояние зависимостей.
Подготовка имён и точная сортировка страниц
Имя файла для img2pdf не несёт номера страницы как отдельное поле: последовательность определяется тем, в каком порядке оболочка или список передали аргументы. Поэтому scan-1.jpg, scan-2.jpg и scan-10.jpg опасны при обычной текстовой сортировке — десятая страница может оказаться между первой и второй. Дополняйте номера нулями до общей длины: scan-001.jpg, scan-002.jpg, scan-010.jpg.
При объединении нескольких партий добавляйте составной ключ: номер тома, тетради, стороны и страницы. Например, v01-s001-front.jpg и v01-s001-back.jpg сортируются предсказуемее, чем произвольные названия камеры. Не переименовывайте исходники без журнала соответствия, если важна доказуемость происхождения; можно создать каталог ссылок или копий с нормализованными именами.
Системная локаль влияет на порядок символов, регистра и чисел. В воспроизводимом shell-сценарии задайте локаль сортировки явно либо сформируйте список Python-кодом с числовым ключом. Сохраните готовый NUL-разделённый список до запуска. Его можно преобразовать в читаемый отчёт, заменив нулевые байты переводами строк только для просмотра.
Проверьте расширения без учёта регистра: камера может создать JPG, а сканер — jpeg. Маска *.jpg не обязана захватить оба варианта. Надёжный сборщик фильтрует допустимые форматы сам, исключает скрытые превью и проверяет, что каждый путь является обычным файлом. После отбора сравните количество записей с ожидаемым числом страниц.
Без потерь не всегда означает меньший файл
Термин без потерь описывает сохранность пикселей, а не обязательное уменьшение объёма. JPEG уже использует эффективное сжатие для фотографий, поэтому прямое вложение обычно даёт PDF лишь немного больше суммы JPEG. PNG может быть очень компактным благодаря палитре, прозрачности и собственным фильтрам; после преобразования в структуру PDF тот же растр иногда занимает больше.
Анимированный GIF хранит различия между кадрами, а PDF требует самостоятельное изображение на каждой странице. Десятки небольших дельта-кадров способны развернуться в большой документ. Многостраничный TIFF, напротив, может уже содержать хорошо сжатые независимые листы. Оценивайте не расширение как таковое, а внутреннее кодирование каждого образца.
Прозрачность добавляет мягкую маску. Палитровый рисунок может потребовать отдельного описания палитры или преобразования. CMYK содержит четыре компоненты вместо трёх. Шестнадцатибитные данные и необычные форматы также меняют путь обработки. Поэтому перед массовой сборкой сделайте матрицу тестов: один типичный файл каждого формата, режим pdfimages -list, размер и визуальное сравнение.
Уменьшать готовый PDF универсальным оптимизатором рискованно: он может пересжать JPEG с потерями, понизить разрешение или изменить цвет. Если нужен меньший файл, оптимизируйте исходные изображения под целевое использование, затем вновь соберите PDF. Так параметры качества остаются контролируемыми и обратимыми благодаря сохранённым оригиналам.
Огромные изображения и предел геометрии PDF
Два ограничения часто путают. Pillow контролирует число декодируемых пикселей, защищая память и процессор. PDF ограничивает обычную страницу диапазоном координат, соответствующим примерно 200 дюймам на сторону. Файл может иметь умеренное число пикселей, но из-за ошибочного dpi получить гигантскую физическую страницу; либо иметь нормальный A4, но сотни миллионов пикселей.
При предупреждении decompression bomb сначала вычислите ширину × высоту и ожидаемый объём распакованного растра. RGB требует ориентировочно три байта на пиксель, RGBA — четыре, а промежуточные копии увеличивают потребление. Отключение лимита не добавляет памяти. Для доверенной панорамы разумнее разрезать изображение на страницы либо использовать машину с контролируемым запасом ресурсов.
При ошибке 200 дюймов задайте физический размер через --imgsize или --pagesize. Например, панорама 30000 пикселей при ошибочных 10 dpi превращается в 3000 дюймов; при 300 dpi она занимает 100 дюймов и укладывается в предел. Выбирайте значение по реальной печати, а не только ради устранения сообщения.
PDF допускает UserUnit для более крупных носителей, но не все просмотрщики, RIP и библиотеки одинаково его поддерживают. Даже если API разрешает oversized, проверьте целевую цепочку. Для карт, чертежей и баннеров часто надёжнее разбить материал на тайлы или согласовать специальный формат с типографией.
Встроенные ICC-профили и предсказуемый цвет
Изображение может содержать ICC-профиль, описывающий связь чисел RGB или CMYK с реальными цветами. img2pdf старается сохранить уместную информацию, но наличие профиля не гарантирует одинаковый вид: просмотрщик должен применять управление цветом, монитор — иметь свой профиль, а печатный процесс — корректный OutputIntent.
У однобитных и серых изображений RGB-профиль может быть бессмысленным и не сохраняться. У JPEG и PNG профиль относится к исходным компонентам. Принудительный --colorspace не выполняет полноценное преобразование по ICC; он меняет интерпретацию. Если нужно привести Adobe RGB к sRGB или RGB к печатному CMYK, сделайте это до img2pdf специализированным цветовым движком.
Для PDF/A профиль в OutputIntent описывает предполагаемое устройство вывода документа. Он не обязан совпадать со встроенным профилем каждого изображения, но вся комбинация должна соответствовать правилам стандарта и вашему архивному процессу. Использование случайного sRGB только ради зелёной отметки валидатора может формально пройти часть проверок, но не решить задачу цвета.
Проверяйте тестовую шкалу и несколько реальных страниц. Сравнивайте не скриншоты разных приложений, а управляемый процесс. Для критичной печати получите proof от типографии и зафиксируйте профиль, версию цветового преобразования и параметры рендеринга до упаковки.
Диагностика через stderr и коды завершения
При выводе PDF в stdout любые текстовые сообщения внутри того же потока разрушили бы документ. Поэтому диагностика отделена и поступает в stderr. В shell можно сохранить её в журнал: img2pdf ... > result.pdf 2> convert.log. Пустой журнал не доказывает корректность страниц, но упрощает поиск предупреждений.
Сценарий должен проверять код завершения сразу после команды. Не продолжайте OCR, загрузку или удаление исходников, если код ненулевой. Записывайте временный PDF в каталог задания и переименовывайте в окончательное имя только после pdfinfo, проверки страниц и, при необходимости, валидации PDF/A.
В Python исключение содержит причину чтения, геометрии или движка. Не подавляйте его общим except Exception: pass. Добавьте имя задания и входного файла, но не печатайте бинарные данные. Для пакетной очереди помечайте ошибочный документ и продолжайте следующий, сохраняя исходники проблемного задания.
Ключ -v полезен при расследовании, но постоянный подробный журнал на огромном архиве может занять много места. Настройте ротацию, сохраните версии зависимостей и хеш команды. Для повторяемой ошибки выделите один минимальный файл, который её воспроизводит.
Автоматизация в CI и серверной очереди
В непрерывной сборке фиксируйте входной список и зависимости. Тест должен создавать небольшой PDF из JPEG, прозрачного PNG, многостраничного TIFF и файла с EXIF Orientation, затем проверять число страниц, размеры и тип встроенных изображений. Такой набор обнаружит изменения Pillow, движка и правил метаданных.
Контейнеру или виртуальному окружению задайте лимиты CPU, памяти и времени. Рабочий процесс с недоверенными входами запускайте от отдельного пользователя без доступа к сети и секретам. Каталог результата монтируйте отдельно. Это снижает последствия повреждённого декодера и случайной перезаписи.
Кэшировать можно по хешу всех входов, нормализованной команде и идентификатору окружения. Один только хеш папки ненадёжен: порядок файлов важен. Ключ --nodate помогает получить одинаковые байты, но проверка должна учитывать двигатель и версии библиотек.
После успешной сборки публикуйте PDF вместе с машинным отчётом: число страниц, размеры, хеш, применённые параметры и результаты валидаторов. Сам журнал stdout не нужен, если PDF писался в файл; stderr сохраняйте хотя бы для заданий с предупреждениями. Исходники удаляйте только по правилам хранения, а не сразу после нулевого кода.
Как доказать отсутствие повторного JPEG-сжатия
Откройте PDF утилитой pdfimages -list и найдите строку страницы. В столбце enc для прямого JPEG ожидается jpeg, а размеры в пикселях должны совпадать с исходником. Затем выполните извлечение с ключом -all. Полученный файл можно сравнить по пикселям с оригиналом.
Побайтовый хеш иногда различается из-за оболочки, которая сохраняет JPEG-поток с другим набором служебных маркеров, но декодированные пиксели остаются теми же. Для строгой проверки используйте инструмент сравнения изображений с метрикой абсолютной ошибки. Ноль означает совпадение пикселей.
Если в списке указано flate, это не обязательно дефект: прозрачный или чересстрочный PNG, палитра, TIFF и иной формат могут требовать другого фильтра. Для JPEG неожиданный flate чаще говорит о том, что файл был декодирован до img2pdf, передан как другое изображение или PDF позже переписал редактор.
Сравнение следует выполнять сразу после img2pdf и после каждой последующей стадии. OCR-программа может сохранить исходные потоки, а может оптимизировать их. Подпись обычно добавляет объекты без изменения старых, но оптимизатор способен перепаковать всё. Контроль на границах процесса показывает, где возникло изменение.
Когда нужен предварительный редактор изображений
img2pdf не удаляет чёрную рамку сканера, не выпрямляет трапецию, не объединяет разворот, не выравнивает фон и не регулирует контраст. Если эти дефекты оставить, они будут точно сохранены в PDF. Сначала обработайте растр, а затем оцените, не ухудшился ли текст из-за агрессивного шумоподавления.
Для JPEG избегайте цепочки многократных сохранений. Выполните все операции за один сеанс и экспортируйте один финальный JPEG с выбранным качеством. Если промежуточная обработка должна быть без потерь, используйте PNG или TIFF, а JPEG создайте только в конце. img2pdf не сможет восстановить данные, потерянные предыдущим сохранением.
Для бинарного текста настройте порог и удаление точек до CCITT Group 4. Для цветных документов проверьте баланс белого и равномерность освещения. Для фотографий выберите профиль и целевой размер. Для чертежей не допускайте изменения пропорций; режим exact в img2pdf может исказить масштаб.
Храните мастер-файлы отдельно от подготовленных страниц. Мастер нужен для повторной обработки, а подготовленная копия — для конкретного PDF. Команда img2pdf, список и параметры редактора вместе образуют воспроизводимый рецепт.
Когда после сборки нужен PDF-редактор или OCR
После упаковки может потребоваться добавить закладки, нумерацию, интерактивное оглавление, подпись, вложения, формы или комментарии. img2pdf не создаёт эти элементы. Передайте готовый контейнер специализированному PDF-инструменту и настройте его так, чтобы изображения не пересжимались без необходимости.
Для поиска и копирования текста используйте OCR. Распознаватель добавляет невидимый текстовый слой либо строит новый PDF. Проверьте язык, ориентацию и соответствие текста изображению. Ошибочный OCR не меняет вид страницы, но ухудшает поиск и доступность.
Если PDF-редактор меняет размер страниц, поворот или боксы, повторно выполните геометрический контроль. Если он оптимизирует картинки, повторите pdfimages и сравнение пикселей. Если добавлена PDF/A-совместимость, запустите валидатор после последнего изменения, а не до него.
Стадии следует располагать осознанно. Обычно сначала готовят изображения, затем собирают PDF, выполняют OCR и навигацию, после чего валидируют и подписывают. Изменение после электронной подписи нарушает её. Оптимизация после PDF/A может нарушить профиль соответствия.
Оценка результата перед массовым запуском
Возьмите не идеальный пример, а набор крайних случаев: самый большой скан, минимальное фото, портрет, альбом, прозрачный PNG, CMYK JPEG, многостраничный TIFF и файл с нестандартным именем. Одна команда должна либо корректно обработать их, либо заранее разделить на разные профили.
Измерьте время, пиковую память и размер. Прямой JPEG покажет лучший сценарий, а прозрачный PNG — тяжёлый. Умножать среднее время на число документов недостаточно: один гигантский файл может определить требования к очереди. Настройте тайм-аут с запасом, но не бесконечный.
Проверьте три просмотра: экран, печатный предварительный просмотр и программный анализ. Убедитесь, что первая и последняя страницы правильные, развороты не смещены, метаданные читаются по-русски, а подсказка масштаба не мешает пользователю. Оцените открытие в целевом мобильном или серверном просмотрщике, если он участвует в процессе.
После теста зафиксируйте профиль команды и не меняйте его молча. Любое обновление зависимостей проходит тот же набор. Так img2pdf используется как измеримый компонент, а не как непрозрачная кнопка конвертации.
Итоговый рабочий подход
img2pdf даёт наилучший результат, когда каждый растр уже готов: обрезан, повёрнут, очищен, имеет правильный цвет и разрешение. После этого программа бережно помещает изображения в PDF, строит страницы заданной геометрии и записывает свойства документа без ненужного ухудшения JPEG или JPEG 2000.
Начинайте с минимальной команды и одного документа. Затем добавляйте только те параметры, действие которых можно проверить: page size, image size, fit, border, rotation, metadata, viewer settings и PDF/A. Сохраняйте тестовый набор с портретной и альбомной страницей, прозрачным PNG, CMYK и многостраничным TIFF, если такие форматы встречаются в работе.
Не ждите от сборщика функций редактора, OCR или фотокоррекции. Эти стадии выполняются другими средствами до или после упаковки. Чёткое разделение задач делает процесс предсказуемым: графический инструмент изменяет пиксели, img2pdf формирует контейнер, распознаватель добавляет текст, а валидатор подтверждает требования к итоговому PDF.
Готовый процесс считается надёжным, когда команда повторяется на чистом окружении, результат проходит структурную и визуальную проверку, а исходники и параметры сохранены. Тогда компактность и скорость img2pdf становятся не случайным эффектом, а контролируемой частью документооборота.