Seiten in PDF aufteilen


67

Ich habe eine gescannte PDF-Datei, die zwei Seiten auf einer virtuellen Seite gescannt hat (Seite in PDF-Datei).

Die Auflösung ist mit guter Qualität. Das Problem ist, dass ich beim Lesen zoomen und von links nach rechts ziehen muss.
Gibt es einen Befehl ( convert,, pdftk...) oder ein Skript, mit dem diese PDF-Datei mit normalen Seiten konvertiert werden kann (eine Seite aus dem Buch = eine Seite in einer PDF-Datei)?


1
Obwohl es nicht die am meisten aufgehobene Antwort ist, hat mich diese wirklich überrascht. Es ist einfach, kurz, schnell und elegant. Ich dachte, es wäre wert, es hier zu erwähnen, da wir manchmal zu faul sind, um zu anderen Antworten zu scrollen ...
Peque

Für die Datensätze kann der umgekehrte Vorgang (Zusammenfügen mehrerer Seiten) über die Befehlszeile (anstelle von "In Datei drucken") pdfnupaus der pdfjamSuite abgerufen werden.
Skippy le Grand Gourou

Antworten:


46

Hier ist ein kleines Python-Skript, das die PyPdf-Bibliothek verwendet und die Aufgabe ordentlich erledigt. Speichern Sie es in einem Skript mit dem Namen un2up(oder was auch immer Sie möchten), machen Sie es ausführbar ( chmod +x un2up) und führen Sie es als Filter aus ( un2up <2up.pdf >1up.pdf).

#!/usr/bin/env python
import copy, sys
from pyPdf import PdfFileWriter, PdfFileReader
input = PdfFileReader(sys.stdin)
output = PdfFileWriter()
for p in [input.getPage(i) for i in range(0,input.getNumPages())]:
    q = copy.copy(p)
    (w, h) = p.mediaBox.upperRight
    p.mediaBox.upperRight = (w/2, h)
    q.mediaBox.upperLeft = (w/2, h)
    output.addPage(p)
    output.addPage(q)
output.write(sys.stdout)

Ignorieren Sie alle Verwerfungswarnungen. Nur die PyPdf-Betreuer müssen sich mit diesen befassen.

Wenn die Eingabe ungewöhnlich ausgerichtet ist, müssen Sie möglicherweise andere Koordinaten verwenden, um die Seiten abzuschneiden. Siehe Warum teilt mein Code nicht jede Seite in einem gescannten PDF korrekt auf?


Nur für den Fall, dass es nützlich ist, hier ist meine frühere Antwort, die eine Kombination aus zwei Werkzeugen und einigen manuellen Eingriffen verwendet:

  • Pdfjam (mindestens Version 2.0), basierend auf dem LaTeX-Paket pdfpages , zum Zuschneiden der Seiten;
  • Pdftk , um die linke und rechte Hälfte wieder zusammenzusetzen.

Beide Tools werden benötigt, da pdfpages meines Erachtens nicht in der Lage ist, zwei verschiedene Transformationen auf dieselbe Seite in einem Stream anzuwenden. pdftkErsetzen Sie beim Aufruf von 42 durch die Anzahl der Seiten im Eingabedokument ( 2up.pdf).

pdfjam -o odd.pdf --trim '0cm 0cm 14.85cm 0cm' --scale 1.141 2up.pdf
pdfjam -o even.pdf --trim '14.85cm 0cm 0cm 0cm' --scale 1.141 2up.pdf
pdftk O=odd.pdf E=even.pdf cat $(i=1; while [ $i -le 42 ]; do echo O$i E$i; i=$(($i+1)); done) output all.pdf

Falls Sie nicht über pdfjam 2.0 verfügen, reicht eine PDFLaTeX-Installation mit dem pdfpages-Paket aus (unter Ubuntu: Sie benötigen texlive-latex empfohlen Installieren Sie texlive-latex-recommended und möglicherweise (unter Ubuntu: texlive-fonts empfohlen Installieren Sie texlive-fonts-recommended ), und verwenden Sie den folgenden Treiber Datei driver.tex:

\batchmode
\documentclass{minimal}
\usepackage{pdfpages}
\begin{document}
\includepdfmerge[trim=0cm 0cm 14.85cm 0cm,scale=1.141]{2up.pdf,-}
\includepdfmerge[trim=14.85cm 0cm 0cm 0cm,scale=1.141]{2up.pdf,-}
\end{document}

Führen Sie dann die folgenden Befehle aus und ersetzen Sie 42 durch die Anzahl der Seiten in der Eingabedatei (die aufgerufen werden muss 2up.pdf):

pdflatex driver
pdftk driver.pdf cat $(i=1; pages=42; while [ $i -le $pages ]; do echo $i $(($pages+$i)); i=$(($i+1)); done) output 1up.pdf

Die PyPdf-Bibliothek funktioniert perfekt. Ich habe es nur ein wenig geändert und mit python conv_pdf.py res.pdf ausgeführt . Wie würden Sie Ihr Skript von der Kommandozeile aus ausführen?
Xralf

Ich würde die Version gerne mit pdfjam ausprobieren (wegen der leichten Skalierung), aber nach der Installation des pdfjam-Pakets erkennt meine Shell den pdfjamBefehl nicht.
Xralf

@xralf: Mein Python-Skript liest gerade von der Standardeingabe und schreibt in die Standardausgabe. Die pdfjam-Version erfordert pdfjam 2.0; Es ist nur ein kleiner Wrapper um pdfpages und ich habe das Bit von LaTeX hinzugefügt, das es generiert, damit Sie es direkt verwenden können. Das Problem mit der Skalierung ist wahrscheinlich mit pypdf lösbar. Es könnte sich um ein Problem mit der Seitengröße handeln.
Gilles

Vielen Dank, der Unterschied liegt in einer etwas schlechteren Auflösung, aber das spielt keine Rolle. Ich werde darauf zurückkommen, wenn ich mehr über Latex weiß (es ist zu komplex für mich und die Lösung ist wirklich gut mit PyPdf).
Xralf

1
@ Gilles Versy nützliches Skript. Ich habe erwartet, so etwas in pdfjam zu sehen, pdftk. Auf jeden Fall möchten einige Benutzer möglicherweise einige Änderungen vornehmen, um Seiten auf andere Achsen aufzuteilen und eine andere Reihenfolge zu verwenden. Dies ist möglich, mit wenigen Zeilen zu ändern und mitq.mediaBox.lowerRight = (w, h/2)
ony

52

Nur eine Ergänzung, da ich Probleme mit dem Python-Skript (und einigen anderen Lösungen) hatte: Für mich mutoolhat es großartig funktioniert. Es ist eine einfache und kleine Ergänzung, die mit dem eleganten mupdfLesegerät geliefert wird. So können Sie versuchen:

mutool poster -y 2 input.pdf output.pdf

Ersetzen Sie ybei horizontalen Teilungen durch x. Und Sie können natürlich beides kombinieren, um komplexere Lösungen zu erhalten.

Wirklich glücklich, dies gefunden zu haben (nach Jahren der täglichen mupdf-Nutzung :)

mutoolAb Version 1.4 wird mupdf mitgeliefert: http://www.mupdf.com/news


Installieren mupdfund mutoolvon der Quelle:

wget http://www.mupdf.com/downloads/mupdf-1.8-source.tar.gz
tar -xvf mupdf-1.8-source.tar.gz
cd mupdf-1.8-source
sudo make prefix=/usr/local install

Oder gehen Sie zur Downloadseite , um eine neuere Version zu finden.


3
Ich hatte ein DJVU ... Ich verwandelte es in ein Postscript (ziemlich schnell), dann in ein PDF (Schildkröte langsam) - und schließlich schnitt mutool es so schnell ab, dass ich dachte, es hätte nicht funktioniert - es hätte geklappt!
Julien Puydt

2
Ja, ich war auch sehr zufrieden mit der Geschwindigkeit.
Martz

3
Dieser ist der einfachste und bessere. mutoolwurde dafür gemacht. Vorsicht -y, ich denke in den meisten Fällen ist das, was Sie wollen -x.
Fiatjaf

2
Dieses Dienstprogramm ist sehr schnell, jedoch habe ich ein Problem mit der Seitenreihenfolge. Der Befehl ordnet die rechte Seite an der ersten Position und die linke Seite an der zweiten zu. Kann mir jemand bei diesem Problem helfen?
Garciparedes


16

Imagemagick schafft das in einem Schritt:

$ convert in.pdf -crop 50%x0 +repage out.pdf

1
Vielen Dank. Wenn ich den -density 400Parameter `hinzufüge, ist die Qualität noch besser.
Xralf

11
Es sieht so aus, als ob convert Raster als Zwischenformat verwendet. Dies führt zu einem unscharfen Aussehen, selbst wenn das Original-PDF Vektorobjekte enthält.
Uhr

Kennt jemand eine Möglichkeit, dies zu tun, ohne dabei Seiteninhalte zu rastern ... oder zumindest eine höhere Auflösung einzustellen?
Tomislav Nakic-Alfirevic

Dadurch wurden Texte in Bilder umgewandelt und PDF-Dateien aus Bildern erstellt. Vielleicht schön für Bilder, aber nutzlos für die Textextraktion.
Andrej

6

Mit dem Befehl Konvertieren von ImageMagick können Sie Ihre Datei in zwei Teile teilen. Siehe http://www.imagemagick.org/Usage/crop/

Wenn ich Sie wäre, würde ich ein (Shell-) Skript wie das folgende schreiben:

  1. Teilen Sie Ihre Datei mit pdfsam : 1 Seite = 1 Datei auf der Festplatte (Format spielt keine Rolle. Wählen Sie eine, die ImageMagick kennt. Ich nehme nur PS oder PDF.
  2. Schneiden Sie für jede Seite die erste Hälfte zu und legen Sie sie in eine Datei mit dem Namen $ {PageNumber} A

  3. Schneiden Sie die zweite Hälfte zu und legen Sie sie in eine Datei mit dem Namen $ {PageNumber} B.

    Sie erhalten 1A.pdf, 1B.pdf, 2A.pdf, 2B.pdf usw.

  4. Fügen Sie dies nun erneut in einem neuen PDF zusammen. Es gibt viele Methoden, um dies zu tun.

1
Würde die Verwendung von ImageMagick die Dateien nicht rastern? Und Sie sollten diesen letzten Teil inline erklären, insbesondere zum Nutzen der Nicht-Frankophonen im Publikum.
Gilles

Weil du kein Französisch verstehen musst. Es wird nur gezeigt, wie Sie ImageMagicks Konvertierung, pdftk oder Ghostscript (gs) alleine verwenden können, um dieses Ziel zu erreichen. Ich benutze gerne pdftk. "Rastern" spielt keine Rolle, da es sich um ein gescanntes Dokument handelt.
Tiktak

6

Basierend auf der Antwort von Gilles und wie ich die Anzahl der PDF-Seiten finde, die ich geschrieben habe

#!/bin/bash

pdforiginal=$1
pdfood=$pdforiginal.odd.pdf
pdfeven=$pdforiginal.even.pdf
pdfout=output_$1
margin=${2:-0}
scale=${3:-1}

pages=$(pdftk $pdforiginal dump_data | grep NumberOfPages | awk '{print $2}')

pagesize=$(pdfinfo $pdforiginal | grep "Page size" | awk '{print $5}')
margin=$(echo $pagesize/2-$margin | bc -l)

pdfjam -o $pdfood --trim "0cm 0cm ${margin}pt 0cm" --scale $scale $pdforiginal
pdfjam -o $pdfeven --trim "${margin}pt 0cm 0cm 0cm" --scale $scale  $pdforiginal

pdftk O=$pdfood E=$pdfeven cat $(i=1; while [ $i -le $pages ]; do echo O$i E$i; i=$(($i+1)); done) output $pdfout

rm $pdfood $pdfeven

Damit ich rennen kann

./split.sh my.pdf 50 1.2

Wobei 50 zum Anpassen des Randes und 1,2 zum Skalieren.


4

Hier ist eine Variante des PyPDF-Codes von Gilles. Diese Funktion funktioniert unabhängig von der Seitenausrichtung:

import copy
import math
import pyPdf

def split_pages(src, dst):
    src_f = file(src, 'r+b')
    dst_f = file(dst, 'w+b')

    input = pyPdf.PdfFileReader(src_f)
    output = pyPdf.PdfFileWriter()

    for i in range(input.getNumPages()):
        p = input.getPage(i)
        q = copy.copy(p)
        q.mediaBox = copy.copy(p.mediaBox)

        x1, x2 = p.mediaBox.lowerLeft
        x3, x4 = p.mediaBox.upperRight

        x1, x2 = math.floor(x1), math.floor(x2)
        x3, x4 = math.floor(x3), math.floor(x4)
        x5, x6 = math.floor(x3/2), math.floor(x4/2)

        if x3 > x4:
            # horizontal
            p.mediaBox.upperRight = (x5, x4)
            p.mediaBox.lowerLeft = (x1, x2)

            q.mediaBox.upperRight = (x3, x4)
            q.mediaBox.lowerLeft = (x5, x2)
        else:
            # vertical
            p.mediaBox.upperRight = (x3, x4)
            p.mediaBox.lowerLeft = (x1, x6)

            q.mediaBox.upperRight = (x3, x6)
            q.mediaBox.lowerLeft = (x1, x2)

        output.addPage(p)
        output.addPage(q)

    output.write(dst_f)
    src_f.close()
    dst_f.close()

2

Die beste Lösung war mutool so:

sudo apt install mupdf-tools pdftk

die Spaltung:

mutool poster -y 2 input.pdf output.pdf

aber dann müssen Sie die Seiten nach links drehen:

pdftk output.pdf cat 1-endleft output rotated.pdf

Immer noch keine Überlappung ...
MUY Belgien

1

Basierend auf der Antwort von Benjamin bei AskUbuntu würde ich die Verwendung des GUI-Tools gscan2pdf empfehlen .

  1. Importieren Sie die PDF-Scandatei in gscan2pdf. Beachten Sie, dass PDF-Dateien, die keine Bilder sind, möglicherweise nicht funktionieren. Scans sind in Ordnung, Sie müssen sich also keine Sorgen machen.

    Bildbeschreibung hier eingeben

  2. Je nach Größe des Dokuments kann es eine Weile dauern. Warten Sie, bis es geladen ist.

  3. Drücken Sie Strg + A , um alle Seiten auszuwählen, und drehen Sie sie bei Bedarf (Strg + Umschalt + C) .

    Bildbeschreibung hier eingeben

  4. Gehen Sie zu Extras >> Aufräumen . Wählen Sie Layout als Doppel- und # Ausgabeseiten = 2 .

    Bildbeschreibung hier eingeben

  5. Klicken Sie auf OK und warten Sie, bis der Auftrag abgeschlossen ist.

    Bildbeschreibung hier eingeben

  6. Speichern Sie die PDF-Datei. Getan.


Getestet, gescheitert mit komplexen PDF-Dokumenten mit einer Vielzahl von Bildern.
MUY Belgien

0

moraes lösung hat bei mir nicht funktioniert. Das Hauptproblem war die x5- und x6-Berechnung. Hier muss ein Offset berücksichtigt werden, dh wenn lowerLeft nicht auf (0,0) steht

Hier ist eine weitere Variante mit zusätzlichen Anpassungen für PyPDF2 und Python 3:

import copy
import math
import PyPDF2
import sys
import io 

def split_pages(src, dst):
    src_f = io.open(src, 'r+b')
    dst_f = io.open(dst, 'w+b')

    input = PyPDF2.PdfFileReader(src_f)
    output = PyPDF2.PdfFileWriter()

    for i in range(input.getNumPages()):
        p = input.getPage(i) 
        q = copy.copy(p)
        q.mediaBox = copy.copy(p.mediaBox)

        x1, x2 = p.cropBox.lowerLeft
        x3, x4 = p.cropBox.upperRight        

        x1, x2 = math.floor(x1), math.floor(x2)
        x3, x4 = math.floor(x3), math.floor(x4)

        x5 = math.floor((x3-x1) / 2 + x1)
        x6 = math.floor((x4-x2) / 2 + x2)

        if x3 > x4:        
            # horizontal
            p.mediaBox.upperRight = (x5, x4)
            p.mediaBox.lowerLeft = (x1, x2)

            q.mediaBox.upperRight = (x3, x4)
            q.mediaBox.lowerLeft = (x5, x2)
        else:
            # vertical        
            p.mediaBox.lowerLeft = (x1, x6)
            p.mediaBox.upperRight = (x3, x4)

            q.mediaBox.upperRight = (x3, x6)
            q.mediaBox.lowerLeft = (x1, x2)

        output.addPage(p)
        output.addPage(q)

    output.write(dst_f)
    src_f.close()
    dst_f.close()

if __name__ == "__main__":
    if ( len(sys.argv) != 3 ):
        print ('Usage: python3 double2single.py input.pdf output.pdf')
        sys.exit(1)

    split_pages(sys.argv[1], sys.argv[2])
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.