2016-04-06 12 views
0

Ich habe ein PDF, das ich gerne aufstellen würde. Es hat 8,5x11 "Seiten, Media-Box und Crop-Box. Ich möchte, dass die PDF 17x11" Seiten haben, durch Zusammenführen angrenzender Seiten. Leider haben die meisten Seiten Inhalte, die entweder vollständig außerhalb oder über die Crop-Box verteilt sind. Da jede Seite nur einen Stream und eine Crop-Box haben kann, wird der überlappende Inhalt sichtbar. Das ist schlecht.Crop PDF Inhalt

Ich möchte nicht meine PDF-Datei rastern, da dies die DPI vor der Zeit beheben würde. Ich werde also nicht in Betracht ziehen, Seiten als Bilder zu exportieren, die Bilder anzuhängen (imagemagick) und dann diese gepaarten Bilder in eine neue PDF einzubetten.

Ich hatte auch Probleme imposing in Postscript - Probleme mit Transparenz, Schriftart Rasterisierung und andere visuelle Störungen während der PDF-> PS-> PDF-Konvertierungen.

Die Antwort sollte skriptfähig sein.

Bisher habe ich versucht:

  • podofo Auferlegung Skripte (LUA)
  • PyPDF2 (Python)
  • ghost
  • Latex

Die Frage "Ghostscript removes content outside the crop box?" deutet darauf hin, Das PDFwrite-Modul von ghostscript erzeugt beim Rendern einer PDF-Ausgabedatei den Inhalt entsprechend der Ausrichtung Box. Also würde ich nur meine pdf durch ghostscript pdfwrite Modul pumpen müssen. Leider funktioniert das nicht.

Ich war dabei aufzugeben, als ich versuchte, das pdf zu einem anderen pdf durch evince zu drucken. Es funktioniert perfekt - Text & Vektor-Elemente innerhalb der Crop-Box sind nicht gerastert, und Elemente außerhalb der Crop-Box sind entfernt (ich habe noch nicht gespreizt Elemente getestet). Die Qualität ist hoch - Auflösung (Seitengröße) und Aussehen sind identisch. In der Tat scheint alles bis auf die Metadaten identisch zu sein.

So:

  • die Frage möglich ist
  • die Antwort bereits vorhanden

Wie kann ich darauf zugreifen?

Ich denke, dass diese Funktionalität von Tasse pdftopdf binär bereitgestellt werden kann. Ich habe keine Probleme beim Aufruf einer externen Binärdatei .... aber ich kann nicht herausfinden, wie man pdftopdf verwendet.

Bearbeiten:Link to test pdf. Es enthält Raster-, Vektor- und Textelemente, von denen einige teilweise durch teilweise transparente Objekte abgedeckt sind und die angrenzende Seiten umfassen. Beim Drucken dieser PDF-Datei über Cups wird der gesamte Inhalt außerhalb der Zuschneide-Box abgeschnitten. Das Öffnen der gefilterten PDF-Datei in Inkscape zeigt jedoch, dass die Off-Page-Elemente einzeln maskiert und nicht beschnitten sind - mit Ausnahme von Text, der getrimmt wird.

Antwort

1

Der Trick besteht darin, Form XObjects zu verwenden, um mehrere Seiten innerhalb einer einzelnen Seite zu erzwingen. Form XObjects kann gesamte PDF Seiten referenzieren und unabhängige Clips beibehalten. PyPDF2 unterstützt Form XObjects nicht, so dass die Zusammenführung den Stream aller Eingabeseiten so vereinheitlicht, dass sie sich die Clip/Media-Box der Ausgabeseite teilen. Ich habe erfolgreich sowohl pdflatex als auch pdfrw (python) verwendet - Testprogramme sind unten aufgeführt. Da Form XObjects von einem ähnlichen Postscript Level 2 Feature abgeleitet sind, wie es von KenS vorgeschlagen wird, sollte es möglich sein, das gleiche Ziel in Ghostscript mit "Seitenclips" zu erreichen. In der Tat he shared a ghostscript 2x1 imposition script in another answer, aber es scheint schrecklich kompliziert. Kombiniert mit den Font-Rasterisierungsproblemen von Popplers pdftops (sogar mit Kompatibilitätsgrad> 1,4), habe ich den Ghostscript-Ansatz aufgegeben.

Latex-Skript abgeleitet von How to stitch two PDF pages together as one big page?. Benötigt pdflatex:

\documentclass{article} 
\usepackage{pdfpages} 
\usepackage[paperwidth=8.5in, paperheight=11in]{geometry} 
\usepackage[multidot]{grffile} 
\pagestyle{plain} 

\begin{document} 
    \setlength\voffset{+0.0in} 
    \setlength\hoffset{+0.0in} 

    \includepdf[ noautoscale=true 
       , frame=false 
       , pages={1} 
       ] 
       {<file.pdf>} 

    \eject \paperwidth=17in \pdfpagewidth=17in \paperheight=11in \pdfpageheight=11in 

    \includepdf[ nup=2x1 
       , noautoscale=true 
       , frame=false 
       , pages={2-,} 
       ] 
       {<file.pdf>} 
\end{document} 

pdfrw (Python-Skript) von pdfrw:examples:booklet abgeleitet. Benötigt pdfrw> = 0,2:

#!/usr/bin/env python3 

# Copyright: 
# Yclept Nemo 
#  2016 
# License: 
# GPLv3 

import itertools 
import argparse 
import pdfrw 

# from itertool recipes in the python documentation 
def grouper(iterable, n, fillvalue=None): 
    "Collect data into fixed-length chunks or blocks" 
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx" 
    args = [iter(iterable)] * n 
    return itertools.zip_longest(*args, fillvalue=fillvalue) 

def pagemerge(page, *pages): 
    merged = pdfrw.PageMerge() + page 
    for page in reversed(list(itertools.takewhile(lambda i: i is not None, reversed(pages)))): 
     merged = merged + page 
     merged[-1].x = merged[-2].x + merged[-2].w 
    return merged.render() 

parser = argparse.ArgumentParser(description='Impose PDF files using Form XOBjects') 

parser.add_argument\ 
    ("source" 
    , help="PDF, source path" 
    , type=pdfrw.PdfReader 
    ) 
parser.add_argument\ 
    ("-s", "--spacer" 
    , help="PDF, spacer path" 
    , type=lambda fp: next(iter(pdfrw.PdfReader(fp).pages), None) 
    ) 
parser.add_argument\ 
    ("target" 
    , help="PDF, target path" 
    ) 

args = parser.parse_args() 

pages = args.source.pages[:1] 

for pair in grouper(args.source.pages[1:], 2): 
    assert pair[0] is not None 
    pages.append(pagemerge(pair[0], args.spacer, pair[1])) 

# include metadata in target 
target = pdfrw.PdfWriter() 
target.addpages(pages) 
target.trailer.Info = args.source.Info 
target.write(args.target) 

Einige Eigentümlichkeiten ab pdfrw 0,2:

  • Beachten Sie, dass die Operationen +=, append und extend nicht für pdfrw.PageMerge definiert sind, auch wenn es sich wie eine Liste verhält . Außerdem verhält sich + wie +=, indem es das linke Objekt ändert.
0

Ghostscript und das PDFwrite-Gerät rasterisieren im Allgemeinen nicht den Inhalt von PDF-Eingabedateien (der Vorbehalt gilt für Fälle mit transparenter Eingabe und Ausgabe < PDF 1.4).

Objekte, die vollständig ausgeschnitten sind, werden nicht in der Ausgabe beibehalten.

Also die kurze Antwort ist, dass dies mit Ghostscript und dem PDFwrite-Gerät vollständig durchführbar sein sollte, mit dem Vorteil, dass es möglich ist, die Seiten auch in einer einzigen Operation zu erzwingen. Ich habe einen Open-Bug-Report über Clipping in einer ähnlichen Situation (Reverse-Imposition), habe aber noch keine Zeit gehabt, darauf einzugehen.

Beachten Sie, dass Ghostscript verwendet normalerweise die MediaBox für den Clip Region, wenn Sie die CropBox verwenden möchten, dann müssen Sie -dUseCropBox an die Befehlszeile hinzuzufügen.

+0

Wie gilt dies für Objekte, die Seiten-/Crop-Box-Grenzen umfassen? Kann Ghostscript solche Seiten (2-> 1) aufstellen, ohne dass der Off-Page-Inhalt den angrenzenden Seiten überlagert wird? – user19087

+0

CUPS scheint dem einzelnen Element Masken hinzuzufügen, anstatt den Inhalt der überspannenden/ausgehenden Seite zu ändern oder zu beschneiden. Kann ich das mit Ghostscript duplizieren? – user19087

+0

Der Seitenclip sollte beibehalten werden (skaliert, übersetzt, usw.), was bedeutet, dass Objekte, die über den Clipbereichen liegen, beibehalten und bei Bedarf abgeschnitten werden. Sie könnten das scheinbare Verhalten von CUPS mit Ghostscript duplizieren, aber es wäre eine beträchtliche Aufgabe, dies zu tun. Sie müssten das pdfwrite-Gerät, das mit Abstand das komplexeste Gerät in Ghostscript ist, umfangreich modifizieren von der Größe). Da der ursprüngliche Seitenclip den Job sowieso erledigen sollte, sehe ich nicht, welcher Gewinn dort wäre. – KenS