16

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

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

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

6 ответов6

22

Вы можете решить это с помощью 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 -->
5

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

3

Итак, после гораздо большего поиска (кажется, что «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
2

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

У меня тоже был отсканированный PDF, в котором было по 2 страницы на каждом листе. Это был отсканированный в брошюру буклет размером 11 x 8,5 (дюйм), который был оставлен сшитым при первоначальном сканировании, поэтому: страница PDF 1 = задняя и передняя обложка; PDF страница 2 = страницы 2 и 3 и т.д. Это хорошо выглядит на экране, но вы не можете распечатать его, а затем сшить его, чтобы сделать больше копий буклета.

Мне нужно было распечатать это на дуплексном копире; то есть превратить его НАЗАД в "навязанный" PDF, готовый к печати. Таким образом, используя решение Курта, я сделал это (гм) "однострочным", чтобы преобразовать его обратно в полстраницы, в правильном порядке страниц снова. Он будет работать для любой высоты и ширины, а также для любого количества страниц. В моем случае у меня был 40-страничный буклет (20 отсканированных страниц в 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"

Вам нужно только изменить первые несколько параметров в этой команде, чтобы указать HEIGHT и WIDTH и ORIG_FILE_PATH. Оставшаяся часть команды вычисляет различные размеры и дважды вызывает gs, затем pdftk. Он даже посчитает страницы вашего сканирования и затем выдаст правильную спецификацию сортировки (для сценария, который я дал).

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

+++ 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

Затем, чтобы получить верстку страницы, необходимую для печатного буклета, вы просто "печатаете" файл order.pdf на нестандартный размер страницы именно того размера, который вам нужен (в моем примере, 5,5 x 8,5), отправляя его в "создание буклета". "инструмент (в моем случае я использовал" Создание буклета Кристофа Фогельбуша для Mac "по адресу http://download.cnet.com/Create-Booklet/3000-2088_4-86349.html).

Полученный PDF-файл теперь вернется к исходному размеру страницы 11 x 8,5 с 2 страницами на листе, но порядок будет таким, что вы можете напечатать его двухсторонним, переплетом по короткому краю и вуаля! у вас будет распечатка, которую вы сможете фотокопировать, а также сложить и вышить седло, воспроизводя оригинальный буклет, даже не разбирая (или даже не видя) оригинал.

Надеюсь, это поможет кому-то!

1

если вам просто нужно вывести все 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
1

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

В 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. ;-)

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .