Seiten eines PDFs in mehrere Seiten hacken [geschlossen]


16

Ich habe eine Reihe von PDF-Dateien, die zwei "echte" Seiten zu einer einzigen PDF-Seite enthalten. Ich würde diese gerne halbieren und jede Hälfte auf eine separate Seite legen. Im Wesentlichen brauche ich etwas, das genau das Gegenteil von pdfnup(oder psnup) tut . Wie kann dieses Kunststück erreicht werden?

Plattform ist Linux, Open Source bevorzugt; Da ich einen großen Haufen davon habe, um etwas zu tun, das per Skript geschrieben werden kann (im Gegensatz zu einer GUI), wäre es schön, wenn ich ihm einfach eine Liste davon geben und es wegkauen lassen könnte.

Auch ein bereits vorhandenes Skript ist nicht die einzige Option. Wenn es Beispielcode gibt, mit dem PDFs auf ähnliche Weise mit einer Bibliothek eines Drittanbieters bearbeitet werden können, kann ich ihn wahrscheinlich dazu zwingen, das zu tun, was ich will.


Antworten:


22

Sie können dies mit Hilfe von Ghostscript lösen. pdftkallein kann das nicht (nach bestem Wissen). Ich gebe Ihnen die Befehlszeilenschritte, um dies manuell zu tun. Es ist einfach, dies als Prozedur zu skripten, auch mit unterschiedlichen Parametern für Seitengrößen und Seitenzahlen. Aber du hast gesagt, dass du das selbst machen kannst ;-)

Wie man das mit Hilfe von Ghostscript löst ...

... und zum Spaß habe ich es kürzlich nicht mit einer Eingabedatei mit "Double-Up" -Seiten gemacht, sondern mit einer mit "Treble-Ups". Sie können die Antwort für diesen Fall hier lesen .

Ihr Fall ist noch einfacher. Sie scheinen etwas Ähnliches zu haben:

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

Sie möchten 1 PDF mit 4 Seiten erstellen, von denen jede die Größe von 421 pt x 595 pt hat.

Erster Schritt

Extrahieren wir zunächst die linken Abschnitte von jeder der Eingabeseiten:

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

Was haben diese Parameter bewirkt?

Erstens wissen, dass in PDF 1 Zoll == 72 Punkte . Dann ist der Rest:

  • -o ...............:Benennt die Ausgabedatei. Implizit auch verwendet -dBATCH -dNOPAUSE -dSAFER.
  • -sDEVICE=pdfwrite : Wir wollen PDF als Ausgabeformat.
  • -g................:Legt die Größe des Ausgabemediums in Pixel fest. Die Standardauflösung von pdfwrite beträgt 720 dpi. Multiplizieren Sie daher mit 10, um eine Übereinstimmung für PageOffset zu erhalten.
  • -c "..............:Fordert Ghostscript auf, das angegebene PostScript-Code-Snippet direkt vor der Haupteingabedatei zu verarbeiten (worauf folgt -f).
  • <</PageOffset ....:Legt die Verschiebung des Seitenbilds auf dem Medium fest. (Für linke Seiten hat die Verschiebung nach natürlich [0 0]keine wirkliche Auswirkung.)
  • -f ...............: Verarbeiten Sie diese Eingabedatei.

Welches Ergebnis hat der letzte Befehl erzielt?

Dieses:

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

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

Zweiter Schritt

Als nächstes die richtigen Abschnitte:

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

Beachten Sie den negativen Versatz, da wir die Seite nach links verschieben, während der Anzeigebereich stationär bleibt.

Ergebnis:

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

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

Letzter Schritt

Jetzt kombinieren wir die Seiten in einer Datei. Wir könnten das auch mit Ghostscript machen, aber wir werden pdftkstattdessen verwenden, weil es für diesen Job schneller ist:

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

Erledigt. Hier ist das gewünschte Ergebnis. 4 verschiedene Seiten im Format 421x595 pt.

Ergebnis:

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

@ Unbekannt: Danke für das Downvoting! Würden Sie bitte einen Kommentar schreiben, der einen Grund dafür angibt?
Kurt Pfeifle

+1 für großartige Verwendung von ASCII-Grafiken und sehr klare Anweisungen. Nur weil ich eine CLI n00b bin, die den Zeilen entgeht, damit sie leichter zu lesen sind, oder?
Geselle Geek

@mullhausen: danke für die korrektur des typos ( 421-> -421). ;-)
Kurt Pfeifle

6

Es gibt ein Tool pdfposter, mit dem PDFs mit mehreren Seiten für eine Eingabeseite erstellt werden können (Kacheln oder Schneiden der Seiten). Es ähnelt dem Tool poster, das dasselbe für PostScript-Dateien ausführt.


pdfposter kann keine überlappenden Inhalte an den Rändern drucken, um das Zusammenfügen von Postern zu vereinfachen. Da es sich jedoch um ein Perl-Skript handelt, ist das Hinzufügen ziemlich einfach.
Matthias Urlichs

3

Nach viel mehr Suche (es scheint, dass "PDF-Schnittseiten" eine weitaus bessere Suche sind) habe ich ein kleines Skript gefunden, unpnupdas posterPDF / PS-Konvertierung verwendet und pdftkgenau das tut, was ich brauche. Es ist ein bisschen weit weg, aber es ist den anderen Methoden, die ich gefunden habe (wie etwa der Verwendung von Imagemagick), weit überlegen, weil es die Seiten nicht rastert, bevor sie ausgespuckt werden.

Für den Fall, dass mobileread aus irgendeinem Grund nicht mehr funktioniert, lautet der Kern des Skripts (lizenziert unter der GPLv2 oder höher von Harald Hackenberg <hackenberggmx.at>) wie folgt:

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
Ich muss es lieben, wenn die Leute ihre eigenen Fragen beantworten. Wenn Sie dies jedoch mit einer grafischen Benutzeroberfläche
Sie

Sie sollten in der Lage sein, mit PDFTK selbst zu tun, was Sie wollen, ohne alle Konvertierungen.
CarlF

@CarlF: Ich dachte, es wäre möglich, aber ich kann nichts in der PDFTK-Manpage sehen, um den Inhalt von Seiten zu manipulieren. Hast du irgendwelche Hinweise für mich?
Womble

@frabjous: Was ist falsch daran, deine eigenen Fragen zu beantworten?
Kurt Pfeifle

1
@womble: Deine Konvertierungen gehen über PS / EPS. Dies führt zwangsläufig zu Qualitätseinbußen (eingebettete Schriften, Transparenzen usw.). Mein Vorschlag vermeidet den riskanten PDF => EPS => PDFWeg und geht den sichereren PDF => PDF => PDFWeg.
Kurt Pfeifle

2

Ich fand die Antwort von Kurt Pfeifle für meine ähnliche Situation sehr hilfreich. Ich dachte, ich könnte meine Modifikation der Lösung mit anderen teilen ...

Ich hatte auch ein gescanntes PDF mit 2 Seiten pro Blatt. Es handelte sich um einen 11 x 8,5 (Zoll) großen Scan einer Broschüre mit Sattelheftung, die beim ursprünglichen Scannen noch geheftet war. PDF-Seite 2 = Seiten 2 und 3 usw. Dies liest sich gut auf dem Bildschirm, aber Sie können es nicht drucken und dann heften, um weitere Kopien der Broschüre zu erstellen.

Ich musste in der Lage sein, dies auf einem Duplexkopierer zu drucken. dh machen Sie es ZURÜCK in ein "auferlegtes" PDF, das zum Drucken bereit ist. Mit Kurts Lösung habe ich diesen (hämmernden) "Einzeiler" gemacht, um ihn wieder in halbe Seiten umzuwandeln, und zwar in der richtigen Seitenreihenfolge. Es funktioniert für jede HÖHE und BREITE sowie für jede Anzahl von Seiten. In meinem Fall hatte ich eine 40-seitige Broschüre (20 gescannte Seiten im 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"

Sie müssen nur die ersten Parameter in diesem Befehl ändern, um HEIGHT und WIDTH sowie ORIG_FILE_PATH anzugeben. Der Rest des Befehls berechnet die verschiedenen Größen und ruft gs zweimal und dann pdftk auf. Es werden sogar die Seiten in Ihrem Scan gezählt und dann die richtige Sortierspezifikation erstellt (für das von mir angegebene Szenario).

Es gibt einige Fortschritte darüber aus, was es tut, was so aussehen wird:

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

Als nächstes "drucken" Sie die bestellte.pdf-Datei auf einer benutzerdefinierten Seitengröße, die genau der Größe entspricht, die Sie benötigen (in meinem Beispiel 5,5 x 8,5), um die für eine gedruckte Broschüre benötigte Seitenerstellung zu erhalten, und senden sie an eine "Broschürenerstellung" "(in meinem Fall habe ich Christoph Vogelbuschs Create Booklet for Mac von http://download.cnet.com/Create-Booklet/3000-2088_4-86349.html verwendet ).

Das resultierende PDF-Dokument hat jetzt wieder die ursprüngliche Seitengröße von 11 x 8,5 mit 2 Seiten pro Blatt. Die Reihenfolge ist jedoch so, dass Sie es doppelseitig, mit kurzer Kante und als Voila drucken können! Sie erhalten einen Ausdruck, den Sie fotokopieren und falten und satteln können, um die Originalbroschüre zu reproduzieren, ohne das Original jemals auseinander zu nehmen (oder sogar unbedingt zu sehen).

Hoffe das hilft jemandem!

-c


1

Basierend auf der obigen Antwort von piptas :

Unter Windows funktionierte das Aufteilen von PDF-Dokumenten im Letter-Format mit einem einzelnen Titelbild am Anfang sehr gut (beachten Sie die Verwendung von [-612 0] im zweiten Schritt; ein positiver Wert erzeugte leere Seiten, weil er in die falsche Richtung verschoben wurde .)

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

Beachten Sie die Verwendung, -dFirstPage=2die gs anweist, mit der Verarbeitung zu beginnen, auf Seite 2.

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

Dadurch wird auf die gleiche Weise die Datei "Rechte Abschnitte.pdf" erstellt. Und jetzt das Titelbild:

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

Als Nächstes habe ich den linken und den rechten Abschnitt in separate PDF-Dateien in einem neuen Verzeichnis aufgeteilt, da ich nicht mit pdftk mithilfe der manuellen Seiteneingabe zusammenführen wollte.

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

Dann füge ich die PDFs in diesem Verzeichnis alphabetisch (und zum Glück heißt das, dass sie in der richtigen Reihenfolge sortiert sind!) Zusammen und starte das Ergebnis erneut durch Ghostscript, um "Warnung: Generationsnummer außerhalb des 0..65535-Bereichs, vorausgesetzt 0. " Von pdftk erzeugte Fehler, die in meinem Ghostscript "itext-paulo-155 (itextpdf.sf.net-lawagie.com)" genannt wurden - es kam auch vor, dass ich die Dateigröße halbierte. Bei einem 4,5-MB-Original betrug das Ergebnis von pdftk 6,7 MB, und die Wiederaufbereitung von gswin32c reduzierte dies auf 3,2 MB.

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

Und wir sind fertig! Sie können die Ordner input_file, cover.pdf, input_temp.pdf, right_sections.pdf und left_sections.pdf löschen. ;-)


1

Wenn Sie nur die PDFs auf der linken Seite in einem Dokument und die PDFs auf der rechten Seite in einem Dokument ausgeben müssen, ist das folgende Skript auf der Grundlage der Antwort von Kurt Pfeifle ausreichend (funktioniert für jede Höhe und Größe) Breite):

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

dann führe es so aus:

$ ./split.sh thepdftosplit.pdf
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.