Ghostscript: конвертация PDF файлов в JPG

ghostscript

В этой заметке рассмотрим установку Ghostscript и конвертацию PDF файлов в JPG, напишем скрипт для массовой конвертации.
В примерах я буду использовать FreeBSD, но решение подойдет для любой платформы, главное обращайте внимание на пути.
Ghostscript — мультиплатформенное решение, дистрибутивы есть для всех основных платформ: Linux, BSD, MacOS и Windows.
По работе приходится сталкиваться с файлами формата PDF.
И их различной обработкой:

Для этого есть всем известный продукт компании Adobe — Adobe Acrobat Pro и в рамках компании логично его использование, да он платный.
Но… Acrobat не предполагает какой-либо автоматизации, в отличии к примеру программ: Adobe PhotoShop в которой есть Actions, inDesign — где есть возможность писать свои скрипты на VBA(Windows Only), JavaScript.
Вообщем мне абсолютно не понятно — почему в продукт, который позиционируется как Профессиональный (Pro)  производитель не добавил интерфейс CLI.
Поэтому приходится строить свои велосипеды:)

Установим:

FreeBSD:

# cd /usr/ports/print/ghostscript9-agpl-base/ && make install clean

Ubuntu:

sudo apt-get install ghostscript

CentOS:

sudo yum install ghostscript.x86_64

MacOS:

Вначале нужно установить Homebrew (пакетный менеджер), делаем все в терминале (Command+Space вбиваем Terminal, жмем Enter)

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" < /dev/null 2> /dev/null
brew install ghostscript

Windows:

Качаем со страницы https://www.ghostscript.com/download/gsdnld.html
И устанавливаем

Проверим установку:

gs -v
GPL Ghostscript 9.52 (2020-03-19)
Copyright (C) 2020 Artifex Software, Inc.  All rights reserved.

Базовая команда конвертации PDF в JPG:

gs -dBATCH -dNOPAUSE -dSAFER -sDEVICE=jpeg -dPDFFitPage=true -dFIXEDMEDIA -sOutputFile=/home/vladimir/pdfs/test.jpg /home/vladimir/jpgs/test.pdf

Получаем на выходе JPG с разрешением в 72 DPI, возможно для каких-то целей (Preview на сайте к примеру) этот файл подойдет, а мы с вами повысим разрешение, добавив соответствующий аргумент -r:

gs -dBATCH -dNOPAUSE -dSAFER -sDEVICE=jpeg -dPDFFitPage=true -dFIXEDMEDIA -r300 -sOutputFile=/home/vladimir/pdfs/test.jpg /home/vladimir/jpgs/test.pdf

Уже лучше, выходной jpg файл имеет разрешение в 300DPI, но хочется еще лучше:), добавим параметр качества сжатия JPG  -dJPEGQ=100:

gs -dBATCH -dNOPAUSE -dSAFER -sDEVICE=jpeg -dPDFFitPage=true -dJPEGQ=100 -dFIXEDMEDIA -r300 -sOutputFile=/home/vladimir/pdfs/test.jpg /home/vladimir/jpgs/test.pdf

Какие еще ключи можно добавить:

  • -sPAPERSIZE= (размер формата: A1-A4 и т.п., формат legal — выведет в правильной пропорции)
  • -gwidthxheight (размер вывода в px, пример: -g240X400)

Это все хорошо, но строка вызова получается достаточно длинной, для частого использования, давайте создадим скрипт которому на вход мы будем давать два аргумента:

  1. Путь до файла PDF
  2. Путь до выходного файла, имя файла будет браться с имени PDF

Создадим скрипт:

vi ~pdf2jpg.sh
#!/bin/sh
#Определим в переменную запуск Ghostscript со всеми нужными нам ключами
pdf2jpg="gs -dBATCH -dNOPAUSE -dSAFER -sDEVICE=jpeg -r300 -dPDFFitPage=true -dJPEGQ=100 -sPAPERSIZE=legal -dFIXEDMEDIA -sOutputFile="

# Сделаем проверку на наличие двух обязательных аргументов
if [ ! -n "$1" ] || [ ! -n "$2" ]
 then
    echo -e "Пожалуйста укажите входной файл PDF и директорию для сохранения jpg файла \nПример: $0 /indir/test.pdf /outdir/"
 else
    # Прибавим к выходной директории имя файла из PDF и заменим расширения на .jpg
    filename=${2}`basename ${1%.*}`.jpg
    
    # Запустим конвертацию
    ${pdf2jpg}${filename} ${1}
    
    # Вывод полного пути до jpg файла
    echo "Файл сохранен:" ${filename}
fi

Сохраняем, делаем исполняемым:

chmod +x ~pdf2jpg.sh

Проверим:

~pdf2jpg.sh temp/test_marvins.pdf  temp/jpg/
GPL Ghostscript 9.52 (2020-03-19)
Copyright (C) 2020 Artifex Software, Inc.  All rights reserved.
This software is supplied under the GNU AGPLv3 and comes with NO WARRANTY:
see the file COPYING for details.
Processing pages 1 through 1.
Page 1
Файл сохранен: temp/jpg/test_marvins.jpg

Все вроде хорошо, но если потребуется преобразовать сотню файлов?
Давайте накидаем по быстрому скрипт пакетной обработки, смысл такой же, как и в предыдущем скрипте.
Будем передавать два аргумента: входная директория и директория для JPG (если указать одинаковые директории, то jpg файлы будут сохранены вместе с PDF).

Создаем скрипт:

vi ~pdfs2jpgs.sh
#!/bin/sh
#Определим в переменную запуск Ghostscript со всеми нужными нам ключами, добавим ключ -q (для "тихого вывода")
pdf2jpg="gs -dBATCH -dNOPAUSE -dSAFER -sDEVICE=jpeg -r300 -dPDFFitPage=true -dJPEGQ=100 -sPAPERSIZE=legal -dFIXEDMEDIA -q -sOutputFile="

# Сделаем проверку на наличие двух обязательных аргументов
if [ ! -n "$1" ] || [ ! -n "$2" ]
 then
    echo -e "Пожалуйста укажите входной файл PDF и директорию для сохранения jpg файла \nПример: $0 /indir/ /outdir/"
 else
    #т.к. ниже будет функция, определим в переменные входную и выходную директорию
    input=${1}
    output=${2}
    #Объявим функцию
    pdfs2jpgs() {
        # Обойдем в цикле for входную директорию и файлы с расширением pdf
        for file in ${input}*.pdf; do

            #Определим в переменную выходную директорию с именем jpg файла
            jpgname=${output}`basename ${file%.*}`.jpg

            # Запустим конвертацию файлов
            ${pdf2jpg}${jpgname} ${file}

            #Сделаем вывод, что и куда сохранилось
            echo "Convert file:" ${file}", save as:" ${jpgname}
        done
   }
   # Вызовем функцию
   pdfs2jpgs
fi

Сохраняем, делам файл исполняемым:

chmod +x ~pdfs2jpgs.sh

Проверим работу скрипта:

~pdfs2jpgs.sh /home/vladimir/temp/ /home/vladimir/temp/jpg/
Convert file: /home/vladimir/temp/001.pdf, save as: /home/vladimir/temp/jpg/001.jpg
Convert file: /home/vladimir/temp/002.pdf, save as: /home/vladimir/temp/jpg/002.jpg
Convert file: /home/vladimir/temp/003.pdf, save as: /home/vladimir/temp/jpg/003.jpg
Convert file: /home/vladimir/temp/004.pdf, save as: /home/vladimir/temp/jpg/004.jpg
Convert file: /home/vladimir/temp/005.pdf, save as: /home/vladimir/temp/jpg/005.jpg
Convert file: /home/vladimir/temp/006.pdf, save as: /home/vladimir/temp/jpg/006.jpg
Convert file: /home/vladimir/temp/007.pdf, save as: /home/vladimir/temp/jpg/007.jpg
Convert file: /home/vladimir/temp/008.pdf, save as: /home/vladimir/temp/jpg/008.jpg
Convert file: /home/vladimir/temp/009.pdf, save as: /home/vladimir/temp/jpg/009.jpg
Convert file: /home/vladimir/temp/010.pdf, save as: /home/vladimir/temp/jpg/010.jpg
Convert file: /home/vladimir/temp/011.pdf, save as: /home/vladimir/temp/jpg/011.jpg
Convert file: /home/vladimir/temp/012.pdf, save as: /home/vladimir/temp/jpg/012.jpg

Все корректно работает при одностраничном PDF файле.

Давайте модифицируем скрипт, для обработки многостраничных файлов PDF:

vi ~pdfs2jpgs.sh
#!/bin/sh
# Сделаем проверку на наличие двух обязательных аргументов
if [ ! -n "$1" ] || [ ! -n "$2" ]
 then
    echo -e "Пожалуйста укажите входной файл PDF и директорию для сохранения jpg файла \nПример: $0 /indir/ /outdir/
    Дополнительные ключи:
    200 - разрешение в dpi
    -r - многостраничный документ (необходимо указать полный путь до файла)
    Пример: $0 /indir/test.pdf /outdir/ 300 -r"
    exit
fi

#т.к. ниже будет функция, определим в переменные входную и выходную директорию
input=${1}
output=${2}

#Установим разрешение по умолчанию в 72dpi
res=""

# Если в третьем аргументе указано разрешение выходного файла
# вносим значение в переменную $res
if [ -n "${3}" ]
    then
           res="-r${3}"
fi

#Определим в переменную запуск Ghostscript со всеми нужными нам ключами, добавим ключ -q (для "тихого вывода")
pdf2jpg="gs -dBATCH -dNOPAUSE -dSAFER -sDEVICE=jpeg ${res} -dPDFFitPage=true -dJPEGQ=100 -sPAPERSIZE=legal -dFIXEDMEDIA -q -sOutputFile="

# Если в четвертом аргументе установлен ключ -r
#- считаем, что делаем многостраничный документ
#здесь же его обрабатываем и выходим
if [ "${4}" == "-r" ]
    then
         jpgname=${2}`basename ${input%.*}`"_%02d.jpg"
         ${pdf2jpg}${jpgname} ${input}
         exit
fi

#Объявим функцию
pdfs2jpgs() {
    # Обойдем в цикле for входную директорию и файлы с расширением pdf
    for file in ${input}*.pdf; do
        #Определим в переменную выходную директорию с именем jpg файла
        jpgname=${output}`basename ${file%.*}`.jpg
        # Запустим конвертацию файлов
        ${pdf2jpg}${jpgname} ${file}
        #Сделаем вывод, что и куда сохранилось
        echo "Convert file:" ${file}", save as:" ${jpgname}
    done
}
# Вызовем функцию
pdfs2jpgs

Теперь скрипт может обрабатывать многостраничный PDF — ключ -r (первым аргументом необходимо указать полный путь до файла).
На выходе мы получим JPG файлы с именем — namepdffile_01.jpg, где префикс _01 — указывает на номер страницы.
Так же четвертым аргументом можно указать выходное разрешение, если не указывать, то jpg файлы будут иметь разрешение в 72dpi.

Пример использования:

  1. Рекурсивная обработка одностраничных PDF файлов с разрешением в 300dpi — ./pdfs2jpgs.sh /indir/ /outdir/ 300
  2. Обработка единичного многостраничного PDF файла с разрешением в 200dpi — ./pdfs2jpgs.sh /indir/test.pdf /outdir/ 300 -r

На этом все, есть вопросы и пожелания — пишите комментарии:)

Рейтинг
( 1 оценка, среднее 3 из 5 )
Понравилась статья? Поделиться с друзьями:
Добавить комментарий

:) :D :( :o 8O :? 8) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen:
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.