Taglia le pagine di un PDF in più pagine [chiuso]


16

Ho un sacco di file PDF che contengono due pagine "reali" in una singola pagina PDF; Vorrei tagliarli a metà e metterli su una pagina separata. In sostanza, ho bisogno di qualcosa che faccia l'esatto contrario di pdfnup(o psnup). Come può essere raggiunta questa impresa?

La piattaforma è Linux, preferibilmente open source; dato che ho un mucchio di questi per fare qualcosa che può essere copiato (al contrario di una GUI) sarebbe bello, quindi posso solo dargli un elenco e farlo masticare.

Uno script preesistente non è nemmeno l'unica opzione; se c'è un codice di esempio per manipolare i PDF in modo simile con una libreria di terze parti, probabilmente posso hackerarlo nel fare quello che voglio.


Risposte:


22

Puoi risolverlo con l'aiuto di Ghostscript. pdftkda solo non posso farlo (per quanto ne so). Ti darò i passaggi della riga di comando per farlo manualmente. Sarà facile copiarlo come una procedura, anche con parametri diversi per dimensioni e numeri di pagina. Ma hai detto che puoi farlo da solo ;-)

Come risolverlo con l'aiuto di Ghostscript ...

... e per il gusto di farlo, ho fatto di recente che non con un file di input con le pagine "double-up", ma con "Treble-up". Puoi leggere la risposta per questo caso qui .

Il tuo caso è ancora più semplice. Sembra che tu abbia qualcosa di simile a questo:

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

Volete creare 1 PDF con 4 pagine, ognuna delle quali ha le dimensioni di 421 pt x 595 pt.

Primo passo

Per prima cosa estraiamo le sezioni di sinistra da ciascuna delle pagine di input:

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

Cosa hanno fatto questi parametri?

Innanzitutto, sappi che in PDF 1 pollice == 72 punti . Quindi il resto è:

  • -o ...............:Nome file di output. Utilizza anche implicitamente -dBATCH -dNOPAUSE -dSAFER.
  • -sDEVICE=pdfwrite : vogliamo PDF come formato di output.
  • -g................:imposta la dimensione del supporto di output in pixel. La risoluzione predefinita di pdfwrite è 720 dpi. Quindi moltiplicare per 10 per ottenere una corrispondenza per PageOffset.
  • -c "..............:chiede a Ghostscript di elaborare lo snippet di codice PostScript specificato appena prima del file di input principale (che deve seguire -f).
  • <</PageOffset ....:imposta lo spostamento dell'immagine della pagina sul supporto. (Naturalmente, per le pagine a sinistra il passaggio da [0 0]non ha alcun effetto reale.)
  • -f ...............: elaborare questo file di input.

Quale risultato ha ottenuto l'ultimo comando?

Questo:

Output file: left-sections.pdf, page 1
+------------+  ^
|            |  |
|     1      |  |
|            |595 pt
|            |  |
|            |  |
|            |  |
+------------+  v

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

Secondo passo

Successivamente, le sezioni giuste:

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

Nota l'offset negativo poiché stiamo spostando la pagina a sinistra mantenendo l'area di visualizzazione fissa.

Risultato:

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

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

Ultimo passo

Ora uniamo le pagine in un unico file. Potremmo farlo anche con ghostscript, ma useremo pdftkinvece, perché è più veloce per questo lavoro:

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

Fatto. Ecco il risultato desiderato. 4 pagine diverse, dimensioni 421x595 pt.

Risultato:

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

@Sconosciuta: grazie per il downvoting! Ti dispiacerebbe scrivere un commento indicando qualche motivo per questo?
Kurt Pfeifle,

+1 per un uso straordinario dell'arte ASCII e istruzioni molto chiare. Solo perché sono un CLI n00b, sfugge alle righe in modo che sia più facile da leggere, giusto?
Journeyman Geek

@mullhausen: grazie per aver corretto l'errore di battitura ( 421-> -421). ;-)
Kurt Pfeifle,

6

Esiste uno strumento pdfposter che può essere utilizzato per creare PDF con più pagine per una pagina di input (affiancando o tagliando le pagine). È simile allo strumento poster, che fa lo stesso per i file PostScript.


pdfposter non gestisce la stampa di contenuti sovrapposti ai bordi, per facilitare l'assemblaggio dei poster. È uno script Perl, tuttavia, quindi è abbastanza facile da aggiungere.
Matthias Urlichs,

3

Quindi, dopo molte più ricerche (sembra che "PDF cut pages" sia una ricerca molto migliore), ho trovato un piccolo script chiamato unpnupche utilizza poster, conversione PDF / PS, e pdftkper fare esattamente ciò di cui ho bisogno. È un po 'lungo, ma è di gran lunga superiore agli altri metodi che ho trovato (come usare imagemagick) perché non rasterizza le pagine prima di sputarle.

Nel caso in cui mobileread scompaia per qualche motivo, il nucleo dello script (concesso in licenza in base alla GPLv2 o in seguito da Harald Hackenberg <hackenberggmx.at>) è il seguente:

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
Devo amarlo quando le persone rispondono alle proprie domande. Tuttavia, se hai bisogno di farlo con una GUI, specialmente se le dimensioni delle pagine non erano pari o se volevi ritagliare ulteriormente ogni lato, dai un'occhiata a Briss: briss.sourceforge.net
frabjous

Dovresti essere in grado di fare ciò che vuoi con PDFTK da solo, senza tutte le conversioni.
CarlF,

@CarlF: ho pensato che sarebbe stato possibile, ma non riesco a vedere nulla nella pagina man di PDFTK per manipolare il contenuto delle pagine. Hai qualche suggerimento per me?
Womble,

@frabjous: cosa c'è di sbagliato nel rispondere alle tue domande?
Kurt Pfeifle,

1
@womble: le tue conversioni vanno via PS / EPS. Ciò è destinato a portare a perdite di qualità (caratteri incorporati, lucidi, ecc.). Il mio consiglio evita il PDF => EPS => PDFpercorso rischioso e va nel PDF => PDF => PDFmodo più sicuro .
Kurt Pfeifle,

2

Ho trovato la risposta di Kurt Pfeifle molto utile per la mia situazione simile. Ho pensato di condividere la mia modifica della soluzione con altri ...

Anch'io avevo un PDF scansionato che aveva 2 pagine su ogni foglio. Era una scansione di 11 x 8,5 (pollici) di un opuscolo cucito a sella che era stato pinzato durante la scansione originale, quindi: PDF pagina 1 = retro e copertina anteriore; PDF pagina 2 = pagine 2 e 3, ecc. Questo legge bene sullo schermo ma non è possibile stamparlo e quindi pinzarlo per fare più copie dell'opuscolo.

Avevo bisogno di poterlo stampare su una copiatrice duplex; cioè trasformarlo INDIETRO in un PDF "imposto", pronto per la stampa. Quindi, usando la soluzione di Kurt, ho realizzato questo (ahem) "one-liner" per riconvertirlo in mezze pagine, nell'ordine corretto delle pagine. Funzionerà per qualsiasi ALTEZZA e LARGHEZZA, e anche per qualsiasi numero di pagine. Nel mio caso, avevo un opuscolo di 40 pagine (20 pagine scansionate nel 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"

Devi solo modificare i primi parametri in questo comando per specificare HEIGHT e WIDTH e ORIG_FILE_PATH. Il resto del comando calcola le varie dimensioni e chiama due volte gs, quindi pdftk. Conterà anche le pagine della scansione e quindi produrrà la specifica di ordinamento corretta (per lo scenario che ho fornito).

Produce alcuni progressi su ciò che sta facendo, che sarà simile a questo:

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

Successivamente, per ottenere l'imposizione della pagina di cui hai bisogno per un opuscolo stampato, devi solo "stampare" ordini.pdf su una dimensione di pagina personalizzata esattamente delle dimensioni necessarie (nel mio esempio, 5,5 x 8,5), inviandola a un "booklet making "strumento (nel mio caso, ho usato il Booklet per Mac di Christoph Vogelbusch da http://download.cnet.com/Create-Booklet/3000-2088_4-86349.html ).

Il PDF risultante tornerà alle dimensioni della pagina originale di 11 x 8,5 con 2 pagine per foglio, ma l'ordinamento sarà tale da poterlo stampare fronte-retro, rilegatura a margine corto e voilà! avrai una stampa che puoi fotocopiare, piegare e cucire a sella, riproducendo il libretto originale senza mai smontare (o anche vedere necessariamente) l'originale.

Spero che questo aiuti qualcuno!

-c


1

Basato sulla risposta di piptas sopra:

Su Windows, per dividere i PDF in formato lettera con una singola immagine di copertina all'inizio, quanto segue ha funzionato perfettamente per me (nota l'uso di [-612 0] nel secondo passaggio, un valore positivo ha creato pagine vuote perché ha spinto nel modo sbagliato .)

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

Notare l'uso -dFirstPage=2che indica a gs di iniziare l'elaborazione a pagina 2.

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

Questo crea right-sezioni.pdf allo stesso modo. E ora l'immagine di copertina:

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

Successivamente, poiché non volevo unirmi a pdftk usando l'inserimento manuale della pagina, ho diviso le sezioni sinistra e destra in PDF separati in una nuova directory.

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

Quindi unisco i PDF in quella directory, in ordine alfabetico (e per fortuna significa che sono ordinati nell'ordine giusto!) E ho anche eseguito nuovamente il risultato tramite ghostscript per correggere "Avvertenza: numero di generazione fuori dall'intervallo 0..65535, supponendo 0." errori prodotti da pdftk che ghostscript chiamava "itext-paulo-155 (itextpdf.sf.net-lawagie.com)" - mi è capitato anche di dimezzare le dimensioni del file durante il mio utilizzo. Con un originale da 4,5 MB, il risultato di pdftk è stato di 6,7 MB e il ritrattamento di gswin32c lo ha ridotto a 3,2 MB.

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

E abbiamo finito! Sentiti libero di eliminare la cartella input_file, cover.pdf, input_temp.pdf, right_sections.pdf e left_sections.pdf. ;-)


1

se hai solo bisogno di produrre tutti i PDF sul lato sinistro in un unico documento e i file PDF sul lato destro in un unico documento, il seguente script basato sulla risposta di Kurt Pfeifle farà il trucco (funziona per qualsiasi altezza e larghezza):

$ 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"

quindi eseguirlo in questo modo:

$ ./split.sh thepdftosplit.pdf
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.