Изменение размера PDF с помощью Ghostscript - PullRequest
35 голосов
/ 16 сентября 2011

Я пытаюсь масштабировать PDF, который, например, имеет небольшой размер от A4 до A4.

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

Однако в горизонтальных документах заполнение не добавляется.Поэтому документ будет иметь правильную высоту для A4, но не достаточно широкую, так как отступы не добавляются на стороне документа (как я и надеялся).

Это то, что я использую, чтобы он работал на A4портретные документы:

gs \
 -sOutputFile=output.pdf \
 -sDEVICE=pdfwrite \
 -sPAPERSIZE=a4 \
 -dCompatibilityLevel=1.4 \
 -dNOPAUSE \
 -dBATCH \
 -dPDFFitPage \
  input.pdf

Ответы [ 5 ]

52 голосов
/ 22 сентября 2011

Вы должны добавить переключатель -dFIXEDMEDIA:

gs \
 -o output.pdf \
 -sDEVICE=pdfwrite \
 -sPAPERSIZE=a4 \
 -dFIXEDMEDIA \
 -dPDFFitPage \
 -dCompatibilityLevel=1.4 \
  input.pdf

-dFIXEDMEDIA всегда требуется, если вам нужно задать определенный размер бумаги / страницы / носителя и игнорировать размер бумаги / страницы / носителя, указанный в документе. Поскольку в PDF всегда определен размер бумаги / страницы / носителя (PostScript может иметь или не иметь ...).

(My -o ... короче и избавляет от добавления -dBATCH -dNOPAUSE - но работает только для более поздних версий Ghostscript.)

7 голосов
/ 16 мая 2017

Во-первых, спасибо всем, кто разместил здесь.

У меня есть маленький скрипт под названием pdfScale , в котором собраны части ответов, размещенных здесь.Поэтому я решил отправить обратно свои 2 цента.Я использую смесь ответов Курта и Тима.Больше похоже на Тима, хотя.Я играл с этим в течение нескольких дней, и вот мой частичный вывод о методах, размещенных здесь:

Установить размер бумаги по имени с помощью -sPAPERSIZE

  • Легко передать имя бумаги (например, a4)
  • Может не дать 100% точных размеров точек
  • Может перевернуть пейзаж <> Портрет

Установите размер бумаги в точках PS -dDEVICEWIDTHPOINTS, -dDEVICEHEIGHTPOINTS

  • Обеспечивает получение нужного размера в пунктах
  • Вы можете перевернуть ШИРИНУ <> ВЫСОТАВы сами
  • Вам необходимо знать размеры в баллах
  • Не так просто написать текст, так как вам потребуется новый размер страницы в пунктах, а также потребуетсяРазмеры страниц источника, если вы хотите определить альбомную / книжную ориентацию.
  • Вы также можете установить пользовательские бумаги (любого размера, который вам действительно нужен).
  • Я использовал -dDEVICEWIDTH, -dDEVICEHEIGHTвместо более длинной версии очков, но они оба, кажется, делают одно и то же (оба получают очки).

Потому что мой ударСкрипт уже способен получать размеры исходной страницы, и мне понравилась идея установить пользовательские размеры страниц, я решил сосредоточиться на настройке размера страницы в пунктах.Я также уже включил GS Paper Sizes в свой сценарий (с именами и размерами).Таким образом, получить эту информацию также было легко.

Использование -dFIXEDMEDIA представляется обязательным в обоих случаях, как указывалось ранее.

Вот как мой подход пошел (по сценарию)

  1. Получить исходные размеры страниц PDF (для обнаружения флип)
  2. Получите размер страницы цели в пунктах (например, A4> 595x842)
  3. Проверьте, имеют ли они одинаковую ориентацию или Flip Target, если необходимо
  4. Запустите GS с точками или перевернутыми точками

Когда я пытался исправить проблему с автоповоротом, Я нашел этот другой ответ Курта .Это об использовании -dAutoRotatePages.Просто скопируйте часть его ответа здесь:

  • -dAutoRotatePages=/None - сохраняет ориентацию каждой страницы;
  • -dAutoRotatePages=/All - поворачивает все страницы (или ни одной) в зависимости отсвоего рода «решение большинства»;
  • -dAutoRotatePages=/PageByPage - автоматически поворачивает страницы по отдельности.

Мой сценарий по умолчанию PageByPage, но это настраивается.Это хорошо сработало в моих тестах.Использование -dAutoRotatePages также, по-видимому, уменьшает необходимость предварительного изменения размера страницы, хотя это не одно и то же.Я сохранил оба варианта.

Мое маленькое приложение изначально было создано для масштабирования PDF-файлов (без изменения размера страницы).Затем я добавил функциональность для выполнения одного, другого или обоих.Я все еще не мог сделать все это за один вызов GS.

Это то, что я призываю изменить размер, меняя переменные на реальные значения.Это для формата A4 Portrait с автоматическим вращением PageByPage:

gs \
-q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dSAFER \
-dCompatibilityLevel="1.5" -dPDFSETTINGS="/printer" \
-dColorConversionStrategy=/LeaveColorUnchanged \
-dSubsetFonts=true -dEmbedAllFonts=true \
-dDEVICEWIDTHPOINTS=595 -dDEVICEHEIGHTPOINTS=842 \
-dAutoRotatePages='/PageByPage' \
-dFIXEDMEDIA -dPDFFitPage \
-sOutputFile='../myOutputFile.pdf' \
-f '../input.pdf'

Обратите внимание, что я также использую -dFIXEDMEDIA AND -dPDFFitPage.Поскольку это соответствует размеру страницы, другая часть моего сценария может быть удобной для масштабирования содержимого в PDF после изменения размера (особенно, если пропорция PDF сильно изменилась).И это одна из причин, по которым я всегда запускаю масштабирование после изменения размера в моем скрипте (в смешанном режиме).

По поводу проблем дроби при использовании имени бумаги, у меня это происходило до того, как я округлил преобразованияот мм / дюймов до точек.После того, как я начал их округлять, они, кажется, всегда нужны.Кажется странным, что GS поднимет эти значения.

Так что мой вывод заключается в том, что трудная часть состоит в том, чтобы найти решение, которое работает по всем направлениям на разных документах с разными размерами и ориентациями.Я все еще не уверен, что использую правильное решение.Но, позволяя пользователю изменить функцию «Обнаружение переворота» и «Автоповорот GS», я надеюсь найти решение по крайней мере для большинства случаев.

Я также перестроил большую часть кода в процессе, и теперь его довольно легко прочитать. Может быть полезно проверить это, если вы хотите автоматизировать такую ​​задачу самостоятельно. Также полезно просто масштабировать / изменять размер PDF-файлов, конечно же:

https://github.com/tavinus/pdfScale

PS: pdfScale берет свое начало в этом потоке StackOverflow .

7 голосов
/ 17 сентября 2011

Ваша команда вообще не выполняет никакого масштабирования, она просто берет файл PDF и преобразует его в файл PDF.

Я бы посоветовал вам попробовать добавить -dPDFFitPage, который будет масштабировать страницу вФайл PDF, соответствующий текущему размеру страницы (в данном случае указанному -sPAPERSIZE).

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

6 голосов
/ 15 июня 2015

Кажется, что размер вывода можно (лучше всего) форсировать, указав размер в точках и не используя -dPDFFitPage. Я получал дробные размеры, что было плохо. Следующее предназначено для печати формата A5 с использованием услуги печати по требованию. «Реал» А5 составляет 420х595 баллов. Я обнаружил, что использование -sPAPERSIZE = a5 дает размеры страниц с дробными точками, но это может быть связано с тем, что оригинал был шатким.

gs \
 -o output.pdf \
 -sDEVICE=pdfwrite \
 -dDEVICEWIDTHPOINTS=419 -dDEVICEHEIGHTPOINTS=595 \
 -dFIXEDMEDIA \
 -dCompatibilityLevel=1.4 \
  input.pdf

Чтобы проверить это, я обнаружил, что с помощью PDFshuffler мне удалось экспортировать отдельные страницы, а затем с помощью pdfinfo я смог получить точный размер этих страниц. Это подтвердило, что использование параметров устройства явно помогло.

0 голосов
/ 24 сентября 2014

Обидно, что функции pstops, очень полезного пакета для масштабирование и объединение страниц PostScript, похоже, недоступно для PDF. Есть программа под названием pdftopdf, но она есть (насколько я можно увидеть) сделать то же самое, что и pstops. Вы можете создать файл ps (я печатаю в файл в evince), использовать pstops и затем ps2pdf, но это довольно неуклюже.

...