Оцифровывал намедни случайно попавшие в руки номера «Пионерской правды» и столкнулся с тем, что вменяемо собрать PDF весьма проблематично. Вменяемо в моём понимании — это автоматически, в Linux'овой консоли, из обработанных картинок (в том числе нарезанных на сегменты: отдельно фон в B/W, отдельно фотографии в grayscale, отдельно цветные плашки картинками с палитрой), да с распознанным текстом из djvused-файла в UTF-8, ибо от бастарда hOCR тошнит. hocr2pdf из состава exact-image (его использует pdfsandwich) не подошёл — в XXI веке не умеет UTF-8! hocr-pdf из пакета hocr-tools понимает только hOCR и JPEG, и строго режет: одна картинка — одна страница. Собрал PDF в Scribus'е — оказалось нечем подшить скрытый текстовый слой. В общем, не было в жизни счастья. Пришлось браться за Python…
Написал в итоге две утилитки:
pdfsed-tools. Первая конвертирует hOCR в любимый djvused и обратно с принудительным пересчётом координат, — и теперь, когда правлю распознанный текст вручную, я забочусь только о координатах отдельных слов. Кроме того, конвертор позволяет пересчитать координаты под другое разрешение картинки — полезно, если вы случайно распознали исходник в 1200 dpi, а результат у вас должен быть, скажем, 200 dpi.
Вторая же утилита — это собственно генератор PDF. Работает он по сценарию вроде такого:
Code:set-title "Пионерская правда - 1961-063 (4502) - 8 августа";
set-author "Редактор: М. Н. Чернова";
create-page 842 1190;
draw-text "1/1.djvused";
draw-image "1/1-0-b.png";
draw-image "1/1-0-r-1.png" pos 45 1113 mask 0xffffff;
draw-image "1/1-0-r-2.png" pos 45 833 mask 0xffffff;
draw-image "1/1-0-r-3.png" pos 468 734 mask 0xffffff;
draw-image "1/1-0-r-4.png" pos 108 85 mask 0xffffff;
draw-image "1/1-0-r-5.png" pos 448 405 mask 0xffffff;
draw-image "1/1-1.png" pos 470 819;
create-page;
draw-text "2/2.djvused";
draw-image "2/2-0-b.png";
draw-image "2/2-1.png" pos 79 742 mask 0xffffff;
draw-image "2/2-2.png" pos 253 89;
draw-image "2/2-3.png" pos 554 89;
create-page;
draw-text "3/3.djvused";
draw-image "3/3-0-b.png";
draw-image "3/3-1.png" pos 56 510 mask 0xffffff;
draw-image "3/3-2.png" pos 541 431;
create-page;
draw-text "4/4.djvused";
draw-image "4/4-0-b.png";
draw-image "4/4-0-r-1.png" pos 66 978 mask 0xffffff;
draw-image "4/4-0-r-2.png" pos 235 359 mask 0xffffff;
draw-image "4/4-0-r-3.png" pos 66 99 mask 0xffffff;
draw-image "4/4-0-r-4.png" pos 572 99 mask 0xffffff;
draw-image "4/4-1.png" pos 234 470;
(Именно так собирался
номер 4502 «Пионерской правды» (PDF, 4,3 Мбайта, Dropbox).)
Что, собственно, делается скриптом? Смотрим:
Code:create-page 842 1190;
Создаём новую страницу размером 842×1190 пунктов.
Code:draw-text "1/1.djvused";
Добавляем на страницу скрытый текст из djvused-файла (можно скормить и hOCR).
Code:draw-image "1/1-0-b.png";
Накладываем на страницу картинку из PNG-файла (не проверял, но уверен, что съест и JPEG; а вот TIFF пока не умеет…). Здесь: весь текст и line-art чёрной краской.
Code:draw-image "1/1-0-r-1.png" pos 45 1113 mask 0xffffff;
Накладываем на то, что уже есть на странице, картинку из другого PNG-файла, да не просто так, а на определённое место (pos 45 1113, координаты в пунктах) и с прозрачным белым цветом (mask 0xffffff). Здесь: один из блоков красной краской.
Ну, и так далее, имитируя, в некотором смысле, набор спусков из плёнок. Начинайте плеваться и задавать вопросы насчёт религии, предпочтений и велосипедостроения.
PS: Ах да, скрипту нужен Python v2.7+ с пакетами PIL/Pillow и ReportLab. Результат рекомендуется оптимизировать чем-нибудь вроде QPDF — со сжатием у ReportLab'а не ахти.