PDF: извлеченные изображения нарезаны / разбиты на плитки

Извлечение изображения с помощью pdfimages и mupdf/mutool пока работает нормально.

Изображения в PDF-файлах, созданных с помощью FreePDF, всегда нарезаны, поэтому одно изображение приводит к созданию нескольких файлов изображений.

Есть ли трюк, чтобы избежать этого? Как я могу использовать результаты pdfshow? Есть ли координаты, чтобы узнать положение, высоту и ширину, чтобы вырезать/обрезать изображение после преобразования PDF в PNG или JPEG?


person Juergen    schedule 19.01.2015    source источник
comment
Можете ли вы опубликовать (ссылку на) образец PDF, который создает нарезанные изображения?   -  person Kurt Pfeifle    schedule 19.01.2015
comment
К сожалению, я не имею никакого влияния на способ создания pdf. FreePdf — это только пример. С большинством pdf я могу извлечь изображения «одним куском». Моя проблема заключается в том, как обрабатывать нарезанные изображения и как получить их как «полное изображение». Моя идея состояла в том, чтобы преобразовать pdf в png и обрезать изображение из этого файла. И я думал, что pdfshow может содержать информацию о положении, ширине и высоте изображения. Но я не могу интерпретировать вывод таким образом. Это пример файла: dropbox.com/s/dlavjithk2o9r9i/test1. pdf?dl=0   -  person Juergen    schedule 20.01.2015
comment
Смотрите мой обновленный ответ...   -  person Kurt Pfeifle    schedule 20.01.2015
comment
Привет Курт, спасибо за подробные объяснения. Я буду работать в эти выходные. Кажется странной проблемой найти автоматизированное решение. Жаль, что нельзя определить координаты позиции. Еще раз спасибо за ваши усилия, Юрген   -  person Juergen    schedule 21.01.2015
comment
Привет, Курт, твои объяснения ведут к основной проблеме. Однако я не нашел решения на данный момент. Nitro pdf и pdflib правильно сливают образ. Я предполагаю, что в фоновом режиме работает процедура сшивания. Еще раз спасибо за ваше время! Юрген   -  person Juergen    schedule 26.01.2015
comment
Ах, я знал, что PDFlib может это сделать. Но года два назад я тестировал NitroPDF с похожей проблемой, и тогда он не смог этого сделать. Приятно осознавать, что за это время он так сильно улучшился!   -  person Kurt Pfeifle    schedule 26.01.2015


Ответы (2)


Наиболее вероятная причина, по которой ваши изображения "нарезаются" после их извлечения, заключается в следующем: они были "нарезаны" еще до их извлечения, так как они живут внутри самого файла PDF.< /сильный>

Не спрашивайте меня, почему некоторые программы для создания PDF делают это.

MS Powerpoint печально известен этим - фоновые изображения, демонстрирующие некоторый градиент, часто нарезаются на десятки тысяч 1x1, 1x2 или 1x8 пикселей и мини-изображения аналогичного размера внутри PDF.


Обновлять

1. Определите масштаб проблемы

Фрагменты изображения образца PDF можно идентифицировать с помощью команды pdfimages -list (для этого требуется последняя версия pdfimages, основанная на форке Poppler, а не xpdf!):

pdfimages -list so-28023312-test1.pdf

page   num  type   width height color comp bpc  enc interp objectID x-ppi y-ppi size ratio
------------------------------------------------------------------------------------------
   1     0 image     271   271  rgb     3   8  jpeg   no       18 0   163   163 26.7K  12%
   1     1 image     271   271  rgb     3   8  jpeg   no       19 0   163   163 21.7K  10%
   1     2 image     271   271  rgb     3   8  jpeg   no       30 0   163   163 22.9K  11%
   1     3 image     271   271  rgb     3   8  jpeg   no       31 0   163   163 21.8K  10%
   1     4 image     132   271  rgb     3   8  jpeg   no       32 0   162   163 9895B 9.2%
   1     5 image     271   271  rgb     3   8  jpeg   no       33 0   163   163 22.5K  10%
   1     6 image     271   271  rgb     3   8  jpeg   no       34 0   163   163 16.5K 7.7%
   1     7 image     271   271  rgb     3   8  jpeg   no       35 0   163   163 16.9K 7.9%
   1     8 image     271   271  rgb     3   8  jpeg   no       36 0   163   163 20.3K 9.4%
   1     9 image     132   271  rgb     3   8  jpeg   no       37 0   162   163 14.5K  14%
   1    10 image     271   271  rgb     3   8  jpeg   no       20 0   163   163 17.1K 8.0%
   1    11 image     271   271  rgb     3   8  image  no       21 0   163   163  107K  50%
   1    12 image     271   271  rgb     3   8  image  no       22 0   163   163 96.7K  45%
   1    13 image     271   271  rgb     3   8  image  no       23 0   163   163  119K  56%
   1    14 image     132   271  rgb     3   8  jpeg   no       24 0   162   163 10.7K  10%
   1    15 image     271    99  rgb     3   8  jpeg   no       25 0   163   161 7789B 9.7%
   1    16 image     271    99  rgb     3   8  jpeg   no       26 0   163   161 6456B 8.0%
   1    17 image     271    99  rgb     3   8  jpeg   no       27 0   163   161 7202B 8.9%
   1    18 image     271    99  rgb     3   8  jpeg   no       28 0   163   161 8241B  10%
   1    19 image     132    99  rgb     3   8  jpeg   no       29 0   162   161 5905B  15%

Поскольку на 1 странице всего 20 разных фрагментов, легко...

  1. ...сначала извлеките их все и конвертируйте в JPEG, а затем
  2. ...затем снова сшейте их вместе.

2. Извлеките фрагменты в формате JPEG.

Следующая команда извлечет фрагменты и попытается сохранить их в формате JPEG (-j) 28023312:

pdfimages so-28023312-test1.pdf 28023312

Есть 3 изображения, которые вышли как PPM. Используйте ImageMagick convert, чтобы сделать из них JPEG (не обязательно, но упрощает командную строку «сшивки»:

for i in 11 12 13; do
  convert 28023312-0${i}.ppm 28023312-0${i}.jpg
done

Вот первые три фрагмента, 280233312-000.jpg, 280233312-001.jpg и 280233312-002.jpg:

3. Снова сшейте 20 фрагментов вместе.

ImageMagick может снова сшить 20 изображений вместе. Глядя на страницу PDF, а также на 20 файлов JPEG, легко определить порядок, в котором они должны быть объединены:

convert                                         \
   \( 28023312-0{00,01,02,03,04}.jpg +append \) \
   \( 28023312-0{05,06,07,08,09}.jpg +append \) \
   \( 28023312-0{10,11,12,13,14}.jpg +append \) \
   \( 28023312-0{15,16,17,18,19}.jpg +append \) \
 -append                                        \
  complete.jpg

Разбор команды:

  1. оператор изображения +append добавляет все перечисленные изображения в горизонтальном порядке.

  2. Строки \( ... \) указывают на обработку в стороне соответствующей части стека изображений (которая должна быть разделена экранированными круглыми скобками). Результат этой горизонтальной операции добавления затем заменит отдельные фрагменты внутри текущего стека изображений.

  3. Последний -append оператор изображения добавляет текущие изображения по вертикали.

Вот получившийся JPEG, снова полностью сшитый вместе:

Сшитые вместе: окончательное изображение

Можно ли это автоматизировать?

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

Чтобы распаковать все или большую часть потоков контента и получить более четкое представление структуры файла PDF, мы могли бы использовать mutool clean -d, podofouncompress или qpdf --qdf.

Я предпочитаю qpdf, 'структурный преобразователь файлов PDF с сохранением содержимого '. Вот команда:

qpdf --qdf --object-streams=disable so-28023312-test1.pdf qdf.pdf

Полученный PDF-файл qdf.pdf легче анализировать, поскольку большинство (но не все) ранее двоичные разделы теперь представлены в кодировке ASCII. Когда вы будете искать вхождения Do внутри этого файла, вы увидите, где вставлены изображения (однако, я не могу дать вам полное руководство по анализу PDF здесь, извините...).

Следующая команда выводит все строки, в которых встречается Do, плюс предыдущая строка (-B 1):

grep -a -B 1 " Do" qdf.pdf

1002 0 0 1002 236 5776.67 cm
/Im0 Do
--
1001 0 0 1002 1237 5776.67 cm
/Im1 Do
--
120.12 0 0 120.24 268.44 693.2004 cm
/Im2 Do
--
[...skipping 15 other output segments...]
--
1002 0 0 369 3237 3406.67 cm
/Im18 Do
--
490 0 0 369 4238 3406.67 cm
/Im19 Do
--
1 0 0 1 204.9037018 508.5130005 cm
/Fm0 Do

Все строки /ImNN Do вставляют изображения (строка /Fm0 Do относится к объекту формы, а не к изображению).

Предыдущие строки, например 490 0 0 369 4238 3406.67 cm, устанавливают текущую матрицу преобразования. Только по этой линии иногда можно сделать вывод о положении изображения и его размере. В случае с этим файлом этого недостаточно — для определения текущей «позиции рисования» потребуется содержимое нескольких предшествующих строк.

person Kurt Pfeifle    schedule 19.01.2015
comment
Первоначальная причина этого, как я слышал много лет назад от кого-то из Adobe, заключалась в поддержке изображений с функциями, не поддерживаемыми в (тогда менее полном) формате PDF. И он говорил в основном о прозрачности. У меня есть ощущение, что это немного ограничено с точки зрения объяснения, но оно того стоит :) - person David van Driessche; 19.01.2015
comment
Плохая новость о вызове pdfimages.exe с -j заключается в том, что он редко инвертирует цвета в черно-белых изображениях. Поэтому я использую его без -j, а затем конвертирую выходные ppm изображения в формат bmp через avconv.exe. В качестве примечания, этот пост действительно тщательный, спасибо за усилия. - person goodvibration; 30.10.2017

FreePDF использует Ghostscript и создает «виртуальный принтер». Когда вы «печатаете в PDF», на самом деле происходит то, что ваше приложение печатает в конвейер печати Windows, который отправляет графические примитивы драйверу принтера Windows PostScript, который отправляет PostScript на монитор порта. Монитор порта FreePDF сохраняет эту программу PostScript на диске. Когда вывод завершен, он запускает Ghostscript, который интерпретирует PostScript и создает файл PDF.

Теперь, если вы не используете поразительно старую версию Ghostscript (что возможно возможно, вы должны проверить!), она возьмет все, что было на входе, и поместит его на выходе. Он не будет нарезать изображения.

Это означает, что, как сказали выше Курт и Дэвид, настоящая причина проблемы заключается в том, что программа PostScript нарезала в ней изображения до того, как Ghostscript их увидел.

Теперь я знаю, что обычно это не так, но это сильно зависит от того, какой драйвер принтера PostScript вы установили, как он настроен, какую версию Windows вы используете и какое приложение управляет принтером.

Как справедливо заметил Дэвид, приложения Microsoft Office имеют дурную привычку отрисовывать определенные типы шаблонов таким образом (для получения «эффекта полупрозрачности» они используют шаблон, в котором ячейка представляет собой маску изображения, а «белые» пиксели прозрачны).

Кроме того, если у вас есть большие фотографии (например) и принтер PostScript настроен на минимальный объем памяти, драйвер может разделить изображение, чтобы не исчерпать память принтера. Очевидно, это проблема конфигурации, потому что на настольном ПК вам пришлось бы использовать образы монстров, чтобы подавить Ghostscript.

В общем, нам нужно от вас гораздо больше информации, прежде чем мы сможем ответить на этот вопрос полностью, но принцип заключается в том, что ущерб был нанесен до того, как он попал в FreePDF. Версия Ghostscript, использованная для создания PDF-файла, будет указана в метаданных PDF-файла, если только FreePDF не решит стереть/перезаписать ее.

Наконец, как указал Курт, вы должны опубликовать ссылку на файл PDF, а в идеале на файл приложения и промежуточный файл PostScript, который использовался для создания PDF.

person KenS    schedule 19.01.2015