Розбийте сторінки PDF на кілька сторінок [закрито]


16

У мене є маса файлів PDF, які містять дві "реальні" сторінки на одній сторінці PDF; Я хотів би розрізати їх навпіл і помістити кожну половину на окрему сторінку. По суті, мені потрібно щось, що робить прямо протилежне pdfnup(або psnup). Як можна досягти цього подвигу?

Платформа - Linux, переважний відкритий код; тому що у мене є велика купа цих робіт, щоб зробити щось, що може бути сценарієм (на відміну від GUI) було б добре, тому я можу просто дати йому список їх і дати йому розжовувати.

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


Відповіді:


22

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

Як вирішити це за допомогою Ghostscript ...

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

Ваш випадок ще простіший. У вас, здається, є щось подібне до цього:

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

Ви хочете створити 1 PDF з 4 сторінок, кожна з яких має розмір 421 pt x 595 pt.

Перший крок

Давайте спочатку витягнемо ліві розділи з кожної із вхідних сторінок:

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 dpi. Отже, помножте на 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 різні сторінки, розміром 421x595 пт.

Результат:

+------------+ +------------+ +------------+ +------------+   ^
|            | |            | |            | |            |   |
|     1      | |     2      | |     3      | |     4      |   |
|            | |            | |            | |            |5595 pt
|            | |            | |            | |            |   |
|            | |            | |            | |            |   |
|            | |            | |            | |            |   |
+------------+ +------------+ +------------+ +------------+   v
<-- 421 pt --> <-- 421 pt --> <-- 421 pt --> <-- 421 pt -->

@ Невідомо: Дякую за заборону! Чи хотіли б ви написати коментар із зазначенням причини цього?
Курт Пфайфл

+1 для чудового використання мистецтва ASCII та дуже чітких інструкцій. Просто виклик, що я CLI n00b, \ n уникнути рядків, щоб його було легше читати, правда?
Подорожник Geek

@mullhausen: дякую за виправлення помилки друку ( 421-> -421). ;-)
Курт Пфайфл

7

Існує інструмент pdfposter, який можна використовувати для створення PDF-файлів з декількох сторінок для однієї вхідної сторінки (плитка чи подрібнення сторінок). Це схоже на інструмент poster, який робить те саме для файлів PostScript.


pdfposter не обробляє друк вмісту, що перекривається на краях, для полегшення складання плаката. Хоча це сценарій Perl, тому його додати досить просто.
Маттіас Урліхс

3

Отже, після багато іншого пошуку (схоже, що "PDF cut pages" - це набагато кращий пошук), я знайшов невеликий скрипт, unpnupякий називається, який використовує poster, перетворення PDF / PS, і pdftkробити саме те, що мені потрібно. Це трохи довгий шлях, але він набагато перевершує інші методи, які я знайшов (наприклад, використання Imagemagick), оскільки він не розширює сторінки, перш ніж їх виплюнути.

Про всяк випадок, якщо мобільне читання з якихось причин відійде, ядро ​​сценарію (ліцензоване на основі 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

1
Мені подобається, коли люди відповідають на власні запитання. Однак якщо вам потрібно було це зробити з графічним інтерфейсом, особливо якщо розміри сторінок не були рівними або ви хочете додатково обрізати кожну сторону, ознайомтеся з Briss
frabjous

Ви повинні мати можливість робити все, що ви хочете, з PDFTK самостійно, без усіх перетворень.
КарлФ

@CarlF: Я подумав, що це можливо, але я не бачу нічого на сторінці "PDFTK man" для маніпулювання вмістом сторінок. Отримали якісь вказівники для мене?
жіночий

@frabjous: Що не так у відповіді на власні запитання?
Курт Пфайфл

1
@womble: ваші конверсії проходять через PS / EPS. Це неодмінно може призвести до втрат якості (вбудовані шрифти, прозорі плівки тощо). Моя пропозиція уникає ризикованого PDF => EPS => PDFмаршруту і йде безпечнішим PDF => PDF => 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

Далі, щоб отримати потрібне накладення сторінки для друкованого буклета, ви просто "надрукували" впорядковану. "(у моєму випадку я використав Крістоф Фогельбуш" Буклет "Створити буклет для Mac з http://download.cnet.com/Create-Booklet/3000-2088_4-86349.html ).

Отриманий PDF файл тепер повернеться до оригінального розміру сторінки 11 х 8,5 з 2 сторінками на аркуші, але замовлення буде таким, що ви зможете надрукувати його двостороннім, коротким переплетенням та voilà! у вас буде роздруківка, яку ви зможете фотокопіювати, складати та зшивати, відтворюючи оригінальний буклет, не розбираючи (а то й обов’язково бачачи) оригінал.

Сподіваюся, це допоможе комусь!

-c


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

Це створює право-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

якщо вам просто потрібно вивести ліві pdfs все в одному документі, а праворуч pdfs - все в одному документі, то наступний сценарій, заснований на відповіді Курта Пфайфле, зробить трюк (працює на будь-якій висоті та ширина):

$ 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.