Уменьшение размера файла PDF с помощью Ghostscript на Linux не помогло

У меня около 50-60 файлов PDF (изображений) размером по 1,5 МБ. Теперь я не хочу, чтобы в моем тезисе были такие большие pdf файлы, которые могли бы загружать, читать и печатать боль в тылу. Поэтому я попытался использовать ghostscript, чтобы сделать следующее:

gs \
  -dNOPAUSE -dBATCH \
  -sDEVICE=pdfwrite \
  -dCompatibilityLevel=1.4 \
  -dPDFSETTINGS="/screen" \
  -sOutputFile=output.pdf \
    L_2lambda_max_1wl_E0_1_zg.pdf

Однако теперь мой 1.4MB pdf имеет размер 1.5MB.

Что я сделал неправильно? Есть ли способ проверить разрешение файла PDF? Мне просто нужны изображения с разрешением 300 точек на дюйм, поэтому предложите использовать convert для изменения разрешения или каким-то образом я могу изменить разрешение изображения (уменьшить его) с помощью gs, так как изображение очень зернистое, когда я использую convert

Как я использую convert:

 convert \
     -units PixelsPerInch \
      ~/Desktop/L_2lambda_max_1wl_E0_1_zg.pdf \
     -density 600 \
      ~/Desktop/output.pdf

Файл примера

http://dl.dropbox.com/u/13223318/L_2lambda_max_1wl_E0_1_zg.pdf

Ответ 1

Если вы запустите Ghostscript -dPDFSETTINGS=/screen, это просто своего рода ярлык. Фактически вы получите (неявно) целый набор настроек, которые вы можете запросить с помощью следующей команды:

gs \
  -dNODISPLAY \
  -c ".distillersettings {exch ==only ( ) print ===} forall quit" \
| grep '/screen'

В моем Ghostscript (v9.06prerelease) я получаю следующий вывод (слегка отредактированный для повышения удобочитаемости):

/screen 
  << /DoThumbnails false 
     /MonoImageResolution 300 
     /ColorImageDownsampleType /Average 
     /PreserveEPSInfo false 
     /ColorConversionStrategy /sRGB 
     /GrayImageDownsampleType /Average 
     /EmbedAllFonts true 
     /CannotEmbedFontPolicy /Warning 
     /PreserveOPIComments false 
     /GrayImageResolution 72 
     /GrayACSImageDict << 
                        /ColorTransform 1 
                        /QFactor 0.76 
                        /Blend 1 
                        /HSamples [2 1 1 2] 
                        /VSamples [2 1 1 2] 
                      >> 
     /ColorImageResolution 72 
     /PreserveOverprintSettings false 
     /CreateJobTicket false 
     /AutoRotatePages /PageByPage 
     /MonoImageDownsampleType /Average 
     /NeverEmbed [/Courier 
                  /Courier-Bold 
                  /Courier-Oblique 
                  /Courier-BoldOblique 
                  /Helvetica 
                  /Helvetica-Bold 
                  /Helvetica-Oblique 
                  /Helvetica-BoldOblique 
                  /Times-Roman 
                  /Times-Bold 
                  /Times-Italic 
                  /Times-BoldItalic 
                  /Symbol 
                  /ZapfDingbats] 
     /ColorACSImageDict << 
                          /ColorTransform 1 
                          /QFactor 0.76 
                          /Blend 1 
                          /HSamples [2 1 1 2] 
                          /VSamples [2 1 1 2] >> 
     /CompatibilityLevel 1.3 
     /UCRandBGInfo /Remove 
>>

Мне интересно, тяжело ли ваши PDF файлы, и если такое преобразование делает неприемлемые вещи (повторная выборка изображений с "неправильными" параметрами), которые увеличивают размер файла...

Если это так (тяжелый PDF файл), скажите так, и я обновлю этот ответ несколькими предложениями....


Update

Я посмотрел образец файла, предоставленный ДНК. Интересно...

Нет, он не содержит любое изображение.

Вместо этого он содержит один большой поток (сжатый с использованием /FlateDecode), который состоит из примерно 700 000+ (!!) операций, в основном однопоточных операций в формате PDF, например:
m (moveto),
l (lineto),
d (setdash),
w (setlinewidth),
S (штрих),
S (closepath и stroke),
W* (eoclip),
rg и rg (setrgbcolor)
и еще несколько.

(Этот PDF-код очень неэффективно написан AFAICS (но выполняет свою работу), потому что он объединяет много коротких штрихов вместо длинных, и почти каждый штрих снова определяет цвет (даже если это то же самое, что и до), и имеет все другие накладные расходы (начальный ход, конечный ход,...).

Ghostscript -dPDFSETTINGS=/screen здесь не имеет любого эффекта (например, нет изображений для downsample). Увеличенный размер файла (до +48 кбайт, если быть точным), вероятно, объясняется тем, что Ghostscript повторно организует некоторые команды внутреннего поглаживания и т.д. В другом порядке, когда он интерпретирует файл.

Значит, вы не можете многое сделать с размером файла PDF...

  • ... если вы не конвертируете каждую из этих страниц PDF в изображение REAL, например PNG:
    gs \
      -o out72.png \
      -sDEVICE=pngalpha \
       L_2lambda_max_1wl_E0_1_zg.pdf

(Я использовал вывод pngalpha для получения прозрачного фона.) Размеры изображения 'out.png' равны 259x213px, размер файла теперь составляет 70 кбайт. Но я уверен, что вам не понравится качество: -)

Качество вывода "плохо", потому что Ghostscript использует разрешение по умолчанию 72 dpi.

Поскольку вы сказали, что хотите иметь 300 точек на дюйм, команда становится следующей:

gs \
  -o out300.png \
  -sDEVICE=pngalpha \
  -r300 \
   L_2lambda_max_1wl_E0_1_zg.pdf

Размер файла теперь 750 кбайт, размеры изображения 1080x889 Пиксели.


Обновление 2

Так как Curiosity в моде в эти дни...:-)... Я попытался сбить размер файла с помощью Adobe Acrobat X Pro на Mac.

Вы хотите знать результаты?

Выполнение "Сохранить как... (PDF с уменьшенным размером файла)" - что для меня в прошлом всегда давало очень хорошие результаты! - создал файл 1,8 ++ MByte (+ 29%). Я предполагаю, что это определенно повышает производительность Ghostscript (размер файла + 3%) в реалистичной перспективе!

Ответ 2

ДНК решила пойти в черно-белых PNG. Способ его создания состоит из двух этапов:

  • Шаг 1: Преобразуйте цветную страницу PDF (например, this) в черно-белую PDF-страницу, используя Ghostscript pdfwrite устройство и параметры
    -dColorConversionStrategy=/Gray и
    -dProcessColorModel=/DeviceGray.
  • Шаг 2: Преобразуйте черно-белую PDF-страницу в PNG, используя Ghostscript pngalpha устройство с разрешением 300 dpi (-r300 в командной строке GS).

Это уменьшает его начальный размер файла от 1,4 МБ до 0,7 МБ.

Но этот рабочий процесс имеет следующий недостаток:

  • Он теряет всю информацию о цвете, не экономя много места на диске по сравнению с выводом цвет, написанным с одинаковым разрешением, непосредственно из PDF!

Существует 2 варианта рабочего процесса ДНК:

  • Одноступенчатое преобразование (цветной) PDF → (цветной) PNG с использованием Ghostscript pngalpha устройства с исходным PDF в качестве входных данных (одинаковые настройки с разрешением 300 dpi). Это имело бы это преимущество:

    • Он сохранит информацию о цвете в выводе PNG, требуя лишь немного свободного места на диске!
  • Одноступенчатое преобразование (цветной) PDF → черно-белая PNG, с использованием Ghostscript pnggray устройства с исходным PDF в качестве входных данных (одинаковые настройки с разрешением 300 dpi) с этим сочетанием преимуществ/недостатков:

    • Он потеряет информацию о цвете в выводе PNG.
    • Он потеряет прозрачный фон, который был сохранен в рабочем процессе ДНК.
    • Он сохранил бы лоты дискового пространства, потому что размер файла уменьшился бы примерно до 20% от выходного потока ДНК.

Итак, вы можете подумать и увидеть размеры и качество выпуска бок о бок, вот оболочка script, чтобы продемонстрировать различия:

#!/bin/bash
#
# Copywrite (c) 2012 <[email protected]>
# License: Creative Commons (CC BY-SA 3.0) 

function echo_do() {
        echo
        echo "Command:     ${*}"
        echo "--------"
        echo
        "${@}"
}

[ -d out ] || mkdir out

echo 
echo "    We assume all PDF pages are 1-page PDFs!"
echo "    (otherwise we'd have to include something like '%03d'"
echo "    into the output filenames in order to get paged output)"
echo

echo '
 # Convert Color PDF to Grayscale PDF.
 # If PDF has transparent background (most do), 
 # this will remain transparent in output.)
 # ATTENTION: since we don't use a resolution,
 # pdfwrite will use its default value of '-r720'.
 # (However, this setting will only affect raster objects...)
'
for i in *.pdf
do
echo_do gs \
 -o "out/${i}---pdfwrite-devicegray-gs.pdf" \
 -sDEVICE=pdfwrite \
 -dColorConversionStrategy=/Gray \
 -dProcessColorModel=/DeviceGray \
 -dCompatibilityLevel=1.4 \
  "${i}"
done

echo '
 # Convert (previously generated) grayscale PDF to PNG using Alpha channel
 # (Alpha channel can make backgrounds transparent)
'
for i in out/*pdfwrite-devicegray*.pdf
do
echo_do gs \
 -o "out/$(basename "${i}")---pngalpha-from-pdfwrite-devicegray-gs.png" \
 -sDEVICE=pngalpha \
 -r300 \
  "${i}"
done

echo '
 # Convert (color) PDF to grayscale PNG using Alpha channel 
 # (Alpha channel can make backgrounds transparent)
'
for i in *.pdf
do
# Following only required for 'pdfwrite' output device, not for 'pngalpha'!
#                -dProcessColorModel=/DeviceGray 
echo_do gs \
 -o "out/${i}---pngalphagray_gs.png" \
 -sDEVICE=pngalpha \
 -dColorConversionStrategy=/Gray \
 -r300 \
  "${i}"
done

echo '
 # Convert (color) PDF to (color) PNG using Alpha channel
 # (Alpha channel can make backgrounds transparent)
'
for i in *.pdf
do
echo_do gs \
 -o "out/${i}---pngalphacolor_gs.png" \
 -sDEVICE=pngalpha \
 -r300 \
  "${i}"
done

echo '
 # Convert (color) PDF to grayscale PNG 
 # (no Alpha channel here, therefor [mostly] white backgrounds)
'
for i in *.pdf
do
echo_do gs \
 -o "out/${i}---pnggray_gs.png" \
 -sDEVICE=pnggray  \
 -r300 \
  "${i}"
done

echo " All output to be found in ./out/ ..."
echo

Запустите этот script и сравните разные выходы бок о бок.

Да, "direct-grayscale-PNG-from-color-PDF-using-pnggray-device" может выглядеть немного хуже (и он не имеет прозрачного фона), чем другой, но он также составляет лишь 20% от размера файла. С другой стороны, если вы захотите купить немного больше качества, жертвуя небольшим дисковым пространством - вы можете использовать -r400 вместо -r300...