Linux-инструмент для нарезки PDF-файлов на несколько страниц

13457
womble

У меня есть куча PDF-файлов, которые создали две «настоящие» страницы для одной PDF-страницы; Я хотел бы нарезать их пополам и поместить каждую половину на отдельную страницу. По сути, мне нужно что-то, что прямо противоположно pdfnup(или psnup). Google и поиск в apt-cache не дают мне любви.

Платформа Linux, с открытым исходным кодом; так как у меня есть большая куча из них, было бы неплохо сделать что-то, что может быть написано в сценарии (в отличие от графического интерфейса), так что я могу просто дать ему список их и сделать это.

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

15
Возможный дубликат [Как я могу разделить страницы PDF посередине?] (Http://superuser.com/questions/235074/how-can-i-split-a-pdfs-pages-down-the-middle) Skippy le Grand Gourou 8 лет назад 0

6 ответов на вопрос

22
Kurt Pfeifle

Вы можете решить это с помощью Ghostscript. pdftkодин не может сделать это (насколько мне известно). Я дам вам шаги командной строки, чтобы сделать это вручную. Это будет легко написать в виде процедуры, также с различными параметрами для размеров страницы и номеров страниц. Но вы сказали, что можете сделать это сами ;-)

Как решить эту проблему с помощью Ghostscript ...

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

Ваш случай еще проще. Кажется, у вас есть что-то похожее на это:

+------------+------------+ ^ | | | | | 1 | 2 | | | | | 595 pt | | | | | | | | | | | | +------------+------------+ v ^ fold v +------------+------------+ ^ | | | | | 3 | 4 | | | | | 595 pt | | | | | | | | | | | | +------------+------------+ v <---------- 842 pt --------> 

Вы хотите создать 1 PDF с 4 страницами, каждая из которых имеет размер 421 пт х 595 пт.

Первый шаг

Давайте сначала извлечем левые разделы из каждой входной страницы:

gs \ -o left-sections.pdf \ -sDEVICE=pdfwrite \ -g4210x5950 \ -c "<</PageOffset [0 0]>> setpagedevice" \ -f double-page-input.pdf 

Что сделали эти параметры?

Во-первых, знайте, что в PDF 1 дюйм == 72 балла . Тогда остальное:

  • -o ...............:Имена выходного файла. Неявно также использует -dBATCH -dNOPAUSE -dSAFER.
  • -sDEVICE=pdfwrite : мы хотим PDF в качестве выходного формата.
  • -g................:устанавливает размер выходного носителя в пикселях. Стандартное разрешение pdfwrite - 720 точек на дюйм. Следовательно, умножьте на 10, чтобы получить соответствие для PageOffset.
  • -c "..............:просит Ghostscript обработать данный фрагмент кода PostScript непосредственно перед основным входным файлом (который должен следовать -f).
  • <</PageOffset ....:устанавливает смещение изображения страницы на носителе. (Конечно, для левых страниц сдвиг [0 0]не имеет реального эффекта.)
  • -f ...............: обработать этот входной файл.

Какой результат достигла последняя команда?

Вот этот:

Output file: left-sections.pdf, page 1 +------------+ ^ | | | | 1 | | | |595 pt | | | | | | | | | +------------+ v  Output file: left-sections.pdf, page 2 +------------+ ^ | | | | 3 | | | |595 pt | | | | | | | | | +------------+ v <-- 421 pt --> 

Второй шаг

Далее правые разделы:

gs \ -o right-sections.pdf \ -sDEVICE=pdfwrite \ -g4210x5950 \ -c "<</PageOffset [-421 0]>> setpagedevice" \ -f double-page-input.pdf 

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

Результат:

Output file: right-sections.pdf, page 1 +------------+ ^ | | | | 2 | | | |595 pt | | | | | | | | | +------------+ v  Output file: right-sections.pdf, page 2 +------------+ ^ | | | | 4 | | | |595 pt | | | | | | | | | +------------+ v <-- 421 pt --> 

Последний шаг

Теперь мы объединяем страницы в один файл. Мы могли бы сделать это и с ghostscript, но мы будем использовать pdftkвместо этого, потому что это быстрее для этой работы:

pdftk \ A=right-sections.pdf \ B=left-sections.pdf \ shuffle \ output single-pages-output.pdf verbose 

Готово. Вот желаемый результат. 4 разных страницы размером 421х595 пт.

Результат:

+------------+ +------------+ +------------+ +------------+ ^ | | | | | | | | | | 1 | | 2 | | 3 | | 4 | | | | | | | | | |5595 pt | | | | | | | | | | | | | | | | | | | | | | | | | | | +------------+ +------------+ +------------+ +------------+ v <-- 421 pt --> <-- 421 pt --> <-- 421 pt --> <-- 421 pt --> 
@ Неизвестно: Спасибо за голосование! Не могли бы вы написать комментарий, указывающий причину этого? Kurt Pfeifle 12 лет назад 0
+1 за потрясающее использование ASCII-искусства и очень четкие инструкции. Просто потому, что я CLI n00b, \ s избегают строк, так что его легче читать, верно? Journeyman Geek 12 лет назад 0
@mullhausen: спасибо за исправление опечатки (`421` ->` -421`). ;-) Kurt Pfeifle 11 лет назад 0
5
Philipp Wendler

Существует инструмент pdfposter, который можно использовать для создания PDF-файлов с несколькими страницами для одной входной страницы (мозаика или разделка страниц). Это похоже на инструмент poster, который делает то же самое для файлов PostScript.

pdfposter не поддерживает печать перекрывающегося содержимого по краям, что упрощает сборку постеров. Это скрипт на Perl, поэтому его довольно легко добавить. Matthias Urlichs 10 лет назад 0
2
womble

Итак, после гораздо большего поиска (кажется, что «PDF-вырезанные страницы» - намного лучший поиск), я нашел небольшой скрипт, unpnupкоторый использует posterпреобразование PDF / PS и pdftkделает именно то, что мне нужно. Это немного долгий путь, но он намного превосходит другие методы, которые я нашел (например, использование imagemagick), потому что он не растеризует страницы до того, как их выплюнуть.

На случай, если mobileread по какой-то причине исчезнет, ​​ядро ​​сценария (лицензированное по GPLv2 или более поздней версии Харальдом Хакенбергом <hackenberggmx.at>) выглядит следующим образом:

pdftk "$1" burst for file in pg*.pdf; do pdftops -eps $file poster -v -pA4 -mA5 -c0% `basename $file .pdf`.eps > `basename $file .pdf`.tps epstopdf `basename $file .pdf`.tps done pdftk pg*.pdf cat output ../`basename $1 .pdf`_unpnuped.pdf 
Должен любить, когда люди отвечают на свои вопросы. Однако, если вам нужно было сделать это с графическим интерфейсом, особенно если размеры страниц были неравномерными или вы хотели обрезать каждую из сторон, проверьте Briss: http://briss.sourceforge.net frabjous 13 лет назад 1
Вы должны быть в состоянии сделать то, что вы хотите с PDFTK самостоятельно, без всех преобразований. CarlF 13 лет назад 0
@CarlF: я думал, что это возможно, но я не вижу ничего на справочной странице PDFTK, чтобы манипулировать содержимым страниц. Есть какие-нибудь указатели для меня? womble 13 лет назад 0
@frabjous: Что не так, отвечая на свои вопросы? Kurt Pfeifle 13 лет назад 0
@womble: ваши конверсии проходят через PS / EPS. Это неизбежно приведет к снижению качества (встроенные шрифты, прозрачные пленки и т. Д.). Мое предложение избегает рискованного маршрута `PDF => EPS => PDF` и идет по более безопасному пути` PDF => PDF => PDF`. Kurt Pfeifle 13 лет назад 1
@pipitas. Ничего такого. Я не был саркастичным, я действительно люблю это. frabjous 13 лет назад 0
Я пробовал pdfsam, jpdf, решение с Perl CAM: PDF, а также с GhostScript .... но безуспешно. После этого я попробовал Briss, и он сделал это довольно легко, и в каждом случае это было сделано за несколько минут ... итак, спасибо! Rostislav Stribrny 10 лет назад 0
@frabjous Если вы знакомы с briss, почему бы не написать ответ на этот вопрос с указанием этого? 把友情留在无盐 8 лет назад 0
@soubunmei b / c briss - это приложение с графическим интерфейсом, так что оно не ответит на вопрос frabjous 8 лет назад 0
2
Chris Thorman

I found the answer by Kurt Pfeifle to be very helpful for my similar situation. I thought I might share my modification of the solution with others...

I too had a scanned PDF that had 2 pages on each sheet. It was an 11 x 8.5 (inch) scan of a saddle-stitched booklet that was left stapled when originally scanned, so: PDF page 1 = back and front cover; PDF page 2 = pages 2 and 3, etc. This reads fine onscreen but you can't print it and then staple it to make more copies of the booklet.

I needed to be able to print this on a duplex copier; i.e. turn it BACK into an "imposed" PDF, ready for printing. So using Kurt's solution, I made this (ahem) "one-liner" to convert it back into half-pages, in the correct page order again. It will work for any HEIGHT and WIDTH, and also for any number of pages. In my case, I had a 40-page booklet (20 scanned pages in the PDF.)

HEIGHT=8.5 WIDTH=11 ORIG_FILE_PATH="original.pdf" \ count=$(set -xe; \ gs -o left.pdf -sDEVICE=pdfwrite \ -g$(perl -e "print(($WIDTH / 2) * 720)")x$(perl -e "print($HEIGHT * 720)") \ -c "<</PageOffset [0 0]>> setpagedevice" \ -f "$ORIG_FILE_PATH" >/dev/null; \ gs -o right.pdf -sDEVICE=pdfwrite \ -g$(perl -e "print(($WIDTH / 2) * 720)")x$(perl -e "print($HEIGHT * 720)") \ -c "<</PageOffset [-$(perl -e "print(($WIDTH / 2) * 72)") 0]>> setpagedevice" \ -f "$ORIG_FILE_PATH" | grep Page | wc -l ); \ echo '>>>>>' Re-ordering $count pages...; \ (set -xe; pdftk A=right.pdf B=left.pdf cat \ A1 `set +xe; for x in $(seq 2 $count); do echo B$x A$x; done` B1 \ output ordered.pdf); \ echo "Done. See ordered.pdf" 

You only need to alter the first few parameters in this command to specify the HEIGHT and WIDTH and ORIG_FILE_PATH. The remainder of the command calculates the various sizes and calls gs twice, then pdftk. It will even count the pages in your scan and then produce the correct sort specification (for the scenario I gave).

It outputs some progress about what it's doing, which will look like this:

+++ perl -e 'print((11 / 2) * 720)' +++ perl -e 'print(8.5 * 720)' ++ gs -o left.pdf -sDEVICE=pdfwrite -g3960x6120 -c '<</PageOffset [0 0]>> setpagedevice' -f original.pdf ++ wc -l ++ grep Page +++ perl -e 'print((11 / 2) * 720)' +++ perl -e 'print(8.5 * 720)' +++ perl -e 'print((11 / 2) * 72)' ++ gs -o right.pdf -sDEVICE=pdfwrite -g3960x6120 -c '<</PageOffset [-396 0]>> setpagedevice' -f original.pdf >>>>> Re-ordering 20 pages... ++ set +xe + pdftk A=right.pdf B=left.pdf cat A1 B2 A2 B3 A3 B4 A4 B5 A5 B6 A6 B7 A7 B8 A8 B9 A9 B10 A10 B11 A11 B12 A12 B13 A13 B14 A14 B15 A15 B16 A16 B17 A17 B18 A18 B19 A19 B20 A20 B1 output ordered.pdf Done. See ordered.pdf 

Next, to get the page imposition you need for a printed booklet, you just "print" ordered.pdf on a custom page size of exactly the size you need (in my example, 5.5 x 8.5), sending it to a "booklet making" tool (in my case, I used Christoph Vogelbusch's Create Booklet for Mac from http://download.cnet.com/Create-Booklet/3000-2088_4-86349.html).

The resulting PDF will now be back to the original page size of 11 x 8.5 with 2 pages per sheet, but the ordering will be such that you can print it double-sided, short-edge binding, and voilà! you will have a printout you can photocopy and fold and saddle-stitch, reproducing the original booklet without ever disassembling (or even necessarily seeing) the original.

Hope this helps someone!

-c

1
Louis

Основываясь на ответе пипт выше:

В Windows для разделения PDF-файлов размером с букву с одним изображением обложки для меня отлично подойдет следующее (обратите внимание на использование [-612 0] на втором шаге, положительное значение создает пустые страницы, потому что оно выдвигается неправильно) .)

gswin32c -o left-sections.pdf -sDEVICE=pdfwrite -dFirstPage=2 -g6120x7920 -c "<</PageOffset [0 0]>> setpagedevice" -f input.pdf

Обратите внимание на использование -dFirstPage=2которого указывает gs начать обработку на странице 2.

gswin32c -o right-sections.pdf -sDEVICE=pdfwrite -dFirstPage=2 -g6120x7920 -c "<</PageOffset [-612 0]>> setpagedevice" -f input.pdf

Это создает right-section.pdf таким же образом. А теперь изображение на обложке:

gswin32c -o cover.pdf -sDEVICE=pdfwrite -dLastPage=1 -g6120x7920 -c "<</PageOffset [0 0]>> setpagedevice" -f input.pdf

Далее, поскольку я не хотел объединяться с pdftk с помощью ручного ввода страниц, я разделил левый и правый разделы на отдельные PDF-файлы в новом каталоге.

mkdir input_file copy cover.pdf input_file\0000.pdf pdftk left-sections.pdf burst output input_file\%04d_A.pdf pdftk right-sections.pdf burst output input_file\%04d_B.pdf 

Затем я присоединяюсь к PDF-файлам в этом каталоге в алфавитном порядке (и, к счастью, это означает, что они отсортированы в правильном порядке!), И я снова запускаю результат через ghostscript, чтобы исправить «Предупреждение: номер поколения выходит за пределы диапазона 0..65535, предполагая, что 0.» ошибки, вызванные pdftk, который ghostscript назвал "itext-paulo-155 (itextpdf.sf.net-lawagie.com)" - это также привело к уменьшению размера файла в два раза при моем использовании. При оригинальном 4,5 МБ результат pdftk составил 6,7 МБ, а повторная обработка gswin32c уменьшила его до 3,2 МБ.

pdftk input_file\*.pdf cat output input_temp.pdf gswin32c -o final_output.pdf -sDEVICE=pdfwrite -f input_temp.pdf 

И мы сделали! Не стесняйтесь удалять папку input_file, cover.pdf, input_temp.pdf, right_sections.pdf и left_sections.pdf. ;-)

1
mulllhausen

если вам просто нужно вывести все pdf с левой стороны, все в одном документе, и pdf с правой стороны, все в одном документе, то следующий скрипт, основанный на ответе Курта Пфайфла, сделает свое дело (работает для любой высоты и ширина):

$ cat split.sh #!/bin/bash   dims=$(pdfinfo "$1" | grep -i "page size:" | cut -d ":" -f2)  width=$(echo "$dims" | cut -d " " -f7)  height=$(echo "$dims" | cut -d " " -f9)  half_width=$(echo "$width * 0.5" | bc -l | cut -d "." -f1)  half_widthtt=$(echo "$width * 5" | bc -l | cut -d "." -f1)  heighttt=$(echo "$height * 10" | bc -l | cut -d "." -f1)   echo "pdf $1 has height $height and width $width"   gs -o "left-$1" -sDEVICE=pdfwrite -g"$half_widthtt"x"$heighttt" -c "<</PageOffset [0 0]>> setpagedevice" -f "$1" gs -o "right-$1" -sDEVICE=pdfwrite -g"$half_widthtt"x"$heighttt" -c "<</PageOffset [-$half_width 0]>> setpagedevice" -f "$1" 

затем запустите его так:

$ ./split.sh thepdftosplit.pdf 

Похожие вопросы