LINUX.ORG.RU

Оценка заполненности pdf файла

 , ,


1

3

Возможно это оффтоп, но может у кого есть какие идеи.
Цель: автоматизировать оценку pdf файла на заполненность изображениями. Например файл из 100 страниц могут содержать 80 страниц просто текста, но другие 20 могут быть забиты по всей странице картинками. Это все для оценки стоимости печати.

UPD. С помощю команды

pdftoppm 1.pdf 1 -jpeg -f 4 -r 300 -singlefile
я получаю 4 страницу файла достаточного качества картинку, но можно ли как-то проанализировать уже этот один файл - jpg на заполненность либо по общей темности картинки либо по объему изображения на фоне общего файла?
UPD2 Командой
convert 1-0.jpg -fill black +opaque white -format "%[fx:mean*100]" info:
Я получаю процент белого фона, то есть незанятой изображением площади страницы. Но вот если страница будет серой, хот чуть чуть, оно всю страницу занесет в 100% заполненность. Ссе же лучше узнать общую темность изображения.

UPD2 - РЕШЕНИЕ ВОПРОСА. На мой взгляд, самым лучшим вариантом оценки заполненности страницы это не указывать профиль, оно само по умолчанию берет CMYK, не пользоваться -sPageList=1,2 ибо не работает этот параметр, по крайней мере у меня, вместо него использовать два параметра: -dFirstPage=9 -dLastPage=9. В итоге имеем вывд польностью заполненой черным страницы:

$ gs -q -dNOPAUSE -dBATCH -dFirstPage=9 -dLastPage=9  -sDEVICE=inkcov -o - 2.pdf
 1.00000  1.00000  1.00000  1.00000 CMYK OK
Подсчет заливки страницы ведется по сумме четырех чисел. 1+1+1+1= 4.00000, что есть 100% Всем спасибо.

UPD3 - Предыдущий вариант не вполне удачный, легкое заполнение может посчитать как полное. Решением является другой -sDEVICE, но обновленного GhostScript:

gs -q -dNOPAUSE -dBATCH -dFirstPage=1 -dLastPage=1 -sDEVICE=ink_cov -o - 2.pdf
Но тут зополненность идет уже в единицах на канал. Не 0.50000 но 50.0000. Также 100% - это уже не 400(4х100) но 300. Подробнее тут:

Так же хорошим вариантом есть оценка заливки сбив все в серые цвета:

convert -density 25 2.pdf -alpha remove -format %[fx:100-100*mean.gray]%% info: > "/tmp/2"
Результат заливки искать в /tmp/2

pdfimages показывает есть ли изображения в pdf и их размер:

pdfimages -list test.pdf 
page   num  type   width height color comp bpc  enc interp  object ID x-ppi y-ppi size ratio
--------------------------------------------------------------------------------------------
   1     0 image     340   144  rgb     3   8  image  no         9  0   295   305 22.8K  16%
   2     1 image     468   144  rgb     3   8  image  no        14  0   294   305 23.3K  12%
   8     2 image    4396  2832  rgb     3   8  image  no        34  0   289   289  201K 0.6%
   9     3 image     468   144  rgb     3   8  image  no        39  0   294   305 23.3K  12%
   9     4 image    3240  1672  rgb     3   8  image  no        41  0   289   290  127K 0.8%
  10     5 image    3240  1672  rgb     3   8  image  no        46  0   289   290  162K 1.0%
  11     6 image    3240  1672  rgb     3   8  image  no        51  0   289   290  558K 3.5%
  12     7 image    3240  1672  rgb     3   8  image  no        56  0   289   290  353K 2.2%
  13     8 image    3240  1672  rgb     3   8  image  no        61  0   289   290  361K 2.3%
  14     9 image    3240  1672  rgb     3   8  image  no        66  0   289   290  335K 2.1%
  15    10 image    3240  1672  rgb     3   8  image  no        71  0   289   290  138K 0.9%
  16    11 image     468   144  rgb     3   8  image  no        76  0   294   305 23.3K  12%
  17    12 image     468   144  rgb     3   8  image  no        81  0   294   305 23.3K  12%
  17    13 image    3240  1672  rgb     3   8  image  no        83  0   289   290 60.8K 0.4%
  18    14 image     468   144  rgb     3   8  image  no        88  0   294   305 23.3K  12%
  19    15 image     468   144  rgb     3   8  image  no        94  0   294   305 23.3K  12%
  21    16 image     468   144  rgb     3   8  image  no       102  0   294   305 23.3K  12%
Может извлекать.

Но здесь есть нюанс, если на pdf страницу наложено, к примеру png изображение с прозрачным фоном на весь лист, то pdfimages покажет весь его размер, хотя именно картинки, которая потребит краску, будет всего 10 процентов.

kostik87 ★★★★★ ()
Последнее исправление: kostik87 (всего исправлений: 1)

а что, печать картинки отличается по цене от печати текста? лол. а если на картинке текст?

тебе надо делить pdf на каналы (цвета, которыми печатает ваш принтер) и считать количество краски в каждом канале, независимо от того, есть на странице картинки или их нет.

я бы попиксельно считал, переводя весь документ в растр, скажем с 200-300 dpi.

anonymous ()
Ответ на: комментарий от abbat81

Нашёл в Imagemagick такой вот простой способ:

$ identify -colorspace CMYK -format '%[fx:mean.c] %[fx:mean.m] %[fx:mean.y] %[fx:mean.k]\n' document.pdf
0.123171 0.0985412 0.127312 0.0825626
0.151662 0.133198 0.155113 0.131946

Статистика по каждой странице — отдельной строкой. Если надо общую статистику по документу, то нужно усреднять столбцы, например, так:

$ identify -colorspace CMYK -format '%[fx:mean.c] %[fx:mean.m] %[fx:mean.y] %[fx:mean.k]\n' document.pdf \
| awk '{ c += $1; m += $2; y += $3; k += $4 } 
       END {
         print "Cyan:    " c/NR;
         print "Magenta: " m/NR;
         print "Yellow:  " y/NR;
         print "Black:   " k/NR;
       }'

Но, по хорошему, надо ещё учитывать цветовой профиль устройства вывода. Для монохромных файлов сам, поди, догадаешься как сделать. С плашечными цветами через ghostscript, наверное, можно, я не знаю.

anonymous ()
Ответ на: комментарий от NightCat

Неплохо. Но почему-то для того же документа, что и в комменте выше, показывает сильно завышенные значения:

$ gs -q -dNOPAUSE -dBATCH -sDEVICE=inkcov -o - document.pdf                                 
 0.26227  0.99939  0.99936  0.21164 CMYK OK
 0.32072  0.99578  0.99578  0.31020 CMYK OK
anonymous ()
Ответ на: комментарий от anonymous

цветовой профиль

Если PDF содержит цветовой профиль, то указывать нужно только профиль выводящего устройства, если не содержит, то нужно указывать оба — текущий профиль файла и профиль выводящего устройства.

Пример со встроенным в файл профилем:

$ convert -density 300 document.pdf \
          -profile CMYK_profile.icc \
          -format '%[fx:mean.c] %[fx:mean.m] %[fx:mean.y] %[fx:mean.k]\n' info: 

Пример для файла без профиля:

$ convert -density 300 document.pdf \
          -profile sRGB_profile.icc \
          -profile CMYK_profile.icc \
          -format '%[fx:mean.c] %[fx:mean.m] %[fx:mean.y] %[fx:mean.k]\n' info:

Imagemagick'овский -colorspace переводит цвета по своим собственным алгоритмам, поэтому содержимое каналов может сильно отличаться от того, которое получается в результате правильного конвертирования с помощью профилей, хоть визуально разница может быть и незаметной.

-density (разрешение растеризации) влияет на результат подсчёта цветов. Чем больше разрешение, тем точнее результат, но медленнее сама растеризация и подсчёт.

Ещё глянь на -intent и -black-point-compensation, они тоже, по идее, влияют на результат.

anonymous ()
Ответ на: комментарий от abbat81

У меня получается (с переводом в grayscale):

$ gs -q -dNOPAUSE -dBATCH -sDEVICE=inkcov -sPageList=1,2 -sOutputICCProfile=default_gray.icc -o - document.pdf

Если в PDF нет встроенного цветового профиля, то его нужно указать через -sDefaultGrayProfile, -sDefaultRGBProfile или -sDefaultCMYKProfile, иначе будут использованы профили по умолчанию.

anonymous ()
Ответ на: комментарий от anonymous

Работает быстрее но не корректно оценивает. Где узнаить список цветовіх профилей, что бы попробовать с разными. Насколько мне известно профили серого тоже разные. Например разные выводы с серым и без - последняя старница полностью залита черным:

$ gs -q -dNOPAUSE -dBATCH -sDEVICE=inkcov -sOutputICCProfile=default_gray.icc -o - 2.pdf
 0.00000  0.00000  0.00000  0.33256 CMYK OK
 0.00000  0.00000  0.00000  0.07169 CMYK OK
 0.00000  0.00000  0.00000  0.06985 CMYK OK
 0.00000  0.00000  0.00000  0.65088 CMYK OK
 0.00000  0.00000  0.00000  0.62463 CMYK OK
 0.00000  0.00000  0.00000  0.70290 CMYK OK
 0.00000  0.00000  0.00000  0.82646 CMYK OK
 0.00000  0.00000  0.00000  0.94978 CMYK OK
 0.00000  0.00000  0.00000  0.82098 CMYK OK
$ gs -q -dNOPAUSE -dBATCH -sDEVICE=inkcov  -o - 2.pdf
 0.03234  0.03234  0.03234  0.03234 CMYK OK
 0.07169  0.07127  0.07168  0.06393 CMYK OK
 0.06955  0.06922  0.06953  0.06438 CMYK OK
 0.32006  0.31865  0.31987  0.29851 CMYK OK
 0.31388  0.31240  0.31374  0.29238 CMYK OK
 0.70720  0.70374  0.70682  0.65456 CMYK OK
 0.99531  0.99228  0.99602  0.68500 CMYK OK
 0.99603  0.99146  0.99556  0.92224 CMYK OK
 1.00000  1.00000  1.00000  1.00000 CMYK OK

И все же проблема обрабатывать определенную страницу, потому что часто приносят сканированный учебник и долго будет все лопатить.

abbat81 ★★ ()
Последнее исправление: abbat81 (всего исправлений: 1)
Ответ на: комментарий от abbat81

Я не знаю почему он неправильно считает. Используй Imagemagick:

$ convert -density 200 document.pdf -profile Gray_profile.icc \
          -format '%[fx:100-100*mean.gray]%%\n' info:

Вывод — заполненность страницы в процентах. Профиль можешь либо из ghostscript взять, там нормальный, либо какой-нибудь из этих, например Gray-elle-V4-rec709.icc. Возможно лучше взять профиль от принтера. Хотя, скорее всего, зависимость количества краски от цвета нелинейная, поэтому без разницы какой профиль, примерно прикинуть любой подойдёт.

Номера страниц можно указывать после имени документа в квадратных скобках. Нумерация начинается с нуля.

$ convert 'document.pdf[0-4,9,14]' ...
anonymous ()