Wie erstelle ich eine leere PDF-Datei über die Befehlszeile?

57

Ich brauchte vor kurzem eine einzelne leere PDF-Seite (8,5 "x 11" Größe) und stellte fest, dass ich nicht wusste, wie man eine von der Befehlszeile aus erstellt.

Beim Ausgeben touch blank.pdfwird eine leere PDF- Datei erstellt . Gibt es ein Befehlszeilentool, das eine leere PDF- Seite erzeugt ?

Brian Fitzpatrick
quelle
Warum brauchst du das? Ich habe ein Druckpaket zum Emulieren von beidseitigem (Duplex-) Drucken auf Nicht-Duplex-Druckern. Dazu muss beim Drucken der geraden Seiten für einen Auftrag mit einer ungeraden Seitenzahl eine zusätzliche leere Seite ausgegeben werden. Dazu sende ich einfach einen Formfeed an lp. Das macht den Trick, ohne eine leere Seite-Datei zu erstellen, etc.
Joe
10
@ Joe Es geht uns nichts an, warum Brian das will oder braucht.
Iain Holder
6
@IainHolder: Ich wünschte, mehr SE-User würden so denken wie du.
Mehrdad
3
@ IainHolder - Ich versuche nicht, in das Geschäft des OP einzusteigen! Ich wollte nur vorschlagen, dass es einen anderen Weg gibt, es zu tun, wenn es so etwas wie das ist, was ich tat. Oft handelt es sich bei solchen Dingen um xy-Probleme ( meta.stackexchange.com/questions/66377/what-is-the-xy-problem ). Daher kann es durchaus angebracht sein, nach dem Ziel zu fragen.
Joe
5
Ich habe gerade den obigen Link im Detail durchgelesen. Ich wusste nicht, dass dies ein so kontroverses Thema ist. TL; DR - Wenn Sie wissen, was Sie tun, möchten Sie nur die Antwort auf die Frage, die Sie gestellt haben. Wenn Sie sich nicht so gut auskennen, haben Sie möglicherweise die falsche Frage gestellt, und die Klärung des tatsächlichen Problems könnte Abhilfe schaffen.
Joe

Antworten:

85

convertMit dem in Ketans Antwort verwendeten ImageMagick-Dienstprogramm können Sie auch so etwas wie schreiben

convert xc:none -page Letter a.pdf

oder

convert xc:none -page A4 a.pdf

oder (für horizontales A4-Papier)

convert xc:none -page 842x595 a.pdf

usw. , ohne eine leere Textdatei zu erstellen. @chbrown hat festgestellt, dass dadurch eine kleinere PDF-Datei erstellt wird.

"xc:" bedeutet "X Constant Image", kann aber auch als "x canvas" angesehen werden. Auf diese Weise können Sie einen einzelnen Farbblock angeben, in diesem Fall keinen. Weitere Informationen finden Sie unter http://imagemagick.org/Usage/canvas/#solid. Hierbei handelt es sich um das De-facto-Handbuch für ImageMagick. [Informationen Rohr ergänzt] (Dinge wie pdf:averwendet werden kann , explizit das Format einer Datei zu erklären. label:'some text', gradient:, rose:und logo: scheinen andere Beispiele für spezielle Dateiformate zu sein.)

Anko schlug vor, diese Änderung als separate Antwort zu veröffentlichen, also mache ich es.

BartekChom
quelle
2
ImageMagick hat nicht wirklich ein nützliches Handbuch. "xc: <foo>" bedeutet "X Constant Image", kann aber auch als "x canvas" angesehen werden. Auf diese Weise können Sie einen einzelnen Farbblock angeben, in diesem Fall keinen . Weitere Informationen finden Sie unter imagemagick.org/Usage/canvas/#solid , dem De-facto-Handbuch für ImageMagick.
Pipe
2
Übrigens funktioniert dies auch mit A4 anstelle von Letter, wenn Sie vernünftige Papierformate wünschen.
TRiG
@TRiG: Natürlich. Es tut mir leid, dass ich Sie in meiner Bearbeitung nicht erwähnt habe, aber in diesem Fall hatte ich es gewusst.
BartekChom
Ich habe dies in die akzeptierte Antwort geändert, da es die ist, die ich in meine~/bin
Brian Fitzpatrick
Kann dieser Befehl geändert werden, um eine PDF-Datei mit n leeren Seiten zu erstellen?
Brian Fitzpatrick
34

Wie das kleinstmögliche GIF muss auch das kleinstmögliche PDF mit leeren Seiten von Hand ausgearbeitet werden, da es so klein ist, dass unnötige, aber harmlose Metadaten einen erheblichen Anteil an der Dateigröße haben und die Komprimierung die Sache tatsächlich vergrößert . Es erfordert auch sorgfältige Beachtung der Regeln in der PDF-Spezifikation darüber, welche Bits der Dateistruktur erforderlich sind und welche nicht. (Wissen Sie , dass Seitenobjekte einen enthalten muss /ResourcesWörterbuch, auch wenn es leer ist, sind aber nicht eine enthalten erforderlich /ContentsStrom?)

Wenn Sie keine PDF 1.5-Objekt- und Querverweis-Streams verwenden (was den Vorteil hat, dass die Datei vollständig in ASCII-Format gedruckt werden kann), sind 317 Byte das Beste, was Sie tun können. Wenn das Kopieren und Einfügen, zur Kenntnis nehmen , dass es einen hinteren Raum auf allen vier der Querverweistabelleneinträge werden muss (die Linien zwischen 0 4und trailer<<...), und dass es nicht eine endgültige Newline nach dem sein soll %%EOF.

%PDF-1.4
1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj
2 0 obj<</Type/Pages/Count 1/Kids[3 0 R]>>endobj
3 0 obj<</Type/Page/MediaBox[0 0 612 792]/Parent 2 0 R/Resources<<>>>>endobj
xref
0 4
0000000000 65535 f 
0000000009 00000 n 
0000000052 00000 n 
0000000101 00000 n 
trailer<</Size 4/Root 1 0 R>>
startxref
178
%%EOF

Durch Ersetzen der Querverweistabelle durch einen manuell erstellten Querverweisdatenstrom der Version 1.5 wird die Datei geringfügig kleiner, da sie nicht mehr druckbar ist (ASCII: 294 Byte). (Der Lesbarkeit halber, ganz zu schweigen von der Möglichkeit, es überhaupt einzugeben, wurde der folgende XRef-Stream hexadezimal ausgegeben, dies wird jedoch nicht im Stream-Wörterbuch wiedergegeben. Um eine gültige PDF-Datei wiederherzustellen, müssen Sie entweder den Hexadezimalauszug durch den folgenden ersetzen entsprechende unformatierte binäre Bytes oder ändern /Length 15zu /Length 30/Filter/ASCIIHexDecodeund übernehmen eine Datei , die 328 Bytes lang ist.)

%PDF-1.5
1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj
2 0 obj<</Type/Pages/Count 1/Kids[3 0 R]>>endobj
3 0 obj<</Type/Page/MediaBox[0 0 612 792]/Parent 2 0 R/Resources<<>>>>endobj
4 0 obj<</Type/XRef/Size 5/W[1 1 1]/Root 1 0 R/Length 15>>stream
0000ff01090001340001650001b200endstream endobj
startxref
178
%%EOF

Ich habe auch versucht, die Objekte 1 bis 3 in einen Objekt-Stream zu packen, aber dies fügt mehr Overhead hinzu, als es spart, selbst wenn der Stream komprimiert ist.

Eine mögliche alternative Formulierung des XRef-Stroms ist

4 0 obj<</Type/XRef/Size 4/W[0 1 0]/Index[1 4]/Root 1 0 R/Length 4>>stream
091365b2endstream endobj

Trotz der erheblichen Einsparungen bei der Länge der eigentlichen Stream-Daten /Index[1 4]verschlingt der zusätzliche Strom bis auf ein Byte alle Einsparungen. Außerdem ist mir unklar, ob Sie das Objekt 0 vollständig aus der Datei entfernen dürfen. (Mir ist auch unklar, ob Objekt 0 die Generationsnummer -1 haben muss. Wenn das nicht erforderlich ist, sparen Sie tatsächlich mehr Bytes mit

4 0 obj<</Type/XRef/Size 5/W[1 1 0]/Root 1 0 R/Length 10>>stream
000001090134016501b2endstream endobj

.)

Um das Papierformat zu ändern, ersetzen Sie es 612 792durch die entsprechende Breite und Höhe, ausgedrückt in PostScript-Punkten (72 PostScript-Punkte = 1 US-Zoll oder 25,4 Millimeter). Zum Beispiel 595 842für A4. Sie können dies in ein Shell-Skript einbetten, das eine leere PDF-Datei in der gewünschten Papiergröße ausgibt. Der einzige schwierige Teil wäre, sicherzustellen, dass der startxrefVersatz auch dann genau bleibt, wenn sich die Größe von Objekt 3 ändert.

zwol
quelle
10
Dies könnte eine lustige Aktivität für seine codegolf.stackexchange.com
Nate Eldredge
5
Ich habe auf meta.codegolf gepostet, um zu sehen, ob so etwas gut ankommt
Nate Eldredge
Dies ist zwar eine gute Lösung, um ein gültiges PDF-Dokument mit einer leeren Seite in einem Texteditor zu erstellen , aber ich halte das nicht für eine Befehlszeilenlösung (wie vom OP gewünscht).
Kurt Pfeifle
23

Wenn Sie convert(ein ImageMagick-Dienstprogramm) installiert haben, können Sie dies tun:

touch a.txt && convert a.txt -page Letter a.pdf
mkc
quelle
1
convertEs gibt auch eine -sizeOption, mit der Sie die Größe der PDF-Ausgabe festlegen können.
MKC
21
Sie können auch schreiben, convert xc:none -page Letter a.pdfohne eine leere txt-Datei zu erstellen.
BartekChom
3
@ BartekChoms Methode scheint eine noch leerere leere Seite zu erzeugen. Es wird eine kleinere Datei erstellt, auf der absolut nichts auswählbar ist, und es werden keine (null)Schriftfehler ausgelöst .
Chbrown
1
@BartekChom Ich möchte das als separate Antwort, damit ich es positiv bewerten kann.
Anko
1
Ich habe convert.im6: improper image header a.txt '@ error / txt.c / ReadTXTImage / 429. convert.im6: keine Bilder definierta.pdf' @ error/convert.c/ConvertImageCommand/3044.
Sigur
12

echo .bp | groff -T pdf > t.pdf

Präsentiert von groff, der am meisten unterschätzten Software der Welt.

James K. Lowden
quelle
2
Ich bekomme groff: can't find `DESC' fileund groff:fatal error: invalid device `pdf'mit groff version 1.22.2 auf centos 7.2.
gla3dr
bash 4.1.2groff 1.18.1.4
Dieselbe
2
@ gla3dr Installiere das komplette groff-Paket und nicht nur groff-base.
Captain Giraffe
1
.bpsteht nur für "break page", weshalb dies ein 2-seitiges Dokument erzeugt. Um ein einseitiges Dokument zu erstellen, gehen Sie noch einfacher vor echo | groff -T pdf > blank.pdf.
Faheem Mitha
sehr schöne lösung, echo .bpsollte aber in der echotat durch ersetzt werden , genau wie @FaheemMitha sagte
myrdd
8

Sie könnten pdfTeX verwenden:

echo '\shipout\hbox{}\end' | pdftex

Dies erzeugt eine leere einzelne Seite texput.pdfvon ungefähr 900 Bytes, die Hälfte dessen, was ImageMagick verwendet.

Dadurch sind Sie jedoch der Standardpapiergröße Ihrer TeX-Installation ausgeliefert. Um die Größe explizit festzulegen, können Sie stattdessen zu LaTeX wechseln:

echo '\documentclass[letterpaper]{article}\usepackage[pass]{geometry}
      \begin{document}\shipout\hbox{}\end{document}' | pdflatex

Eine weitere Möglichkeit wäre die Verwendung des PDF-Treibers von Ghostscript, allerdings mit dem praktischen ps2pdfSkript:

echo showpage | ps2pdf -sPAPERSIZE=letter - blank.pdf

Das ist viel leiser als TeX, erzeugt aber eine weniger kompakte Ausgabe (ca. 2300 Bytes).

Henning Makholm
quelle
1
Ich benutze die Variante echo "" | ps2pdf -sPAPERSIZE=a4 - blank.pdf. Dies ist mit 2200 Bytes etwas kleiner.
Faheem Mitha
echo '\documentclass[letterpaper]{article}\usepackage[pass]{geometry} \begin{document}\shipout\hbox{}\end{document}' | pdflatexschafft article.pdf. Ist es möglich, es blank.pdfdirekt erstellen zu lassen ?
Faheem Mitha
@FaheemMitha: Hmm, ich würde erwarten, dass ps2pdf mit einer leeren Eingabe eine PDF-Datei erzeugt, die keine Seiten enthält - aber wenn ich es versuche, gibt es tatsächlich eine Seite.
Ich frage
@Faheem: Zumindest mit Texlive können Sie den Basisnamen der Ausgabedatei -jobname <basename>über die Befehlszeile festlegen .
Henning Makholm
1
@FaheemMitha: Jede \shipout\hbox{}oder showpageproduziert eine Seite. Sowohl TeX als auch Postscript verfügen über Schleifenkonstrukte, die Sie verwenden können. Es ist jedoch wahrscheinlich einfacher , die Skriptsprache Ihrer Wahl zu verwenden, um den Befehl entsprechend oft zu duplizieren.
Henning Makholm
3

Eine einfache Möglichkeit, ein PDF mit einer leeren Seite zu erstellen, ist die Verwendung von rst2pdf:

echo -e '.. raw:: pdf\n\n   PageBreak' | rst2pdf -o blank.pdf

Nur ein Echo in einem einzelnen Bereich reicht nicht aus. Am Ende erhalten Sie eine PDF-Datei ohne Seiten (was nicht mit einer leeren Datei identisch ist).

Anthon
quelle
2

Geben Sie in der Befehlszeile Folgendes ein:

ps2pdf blank.pdf

Mit dem Befehl ps2pdfwird eine PostScript-Datei in eine PDF-Datei konvertiert

ps2pdf file.ps file.pdf
GAD3R
quelle
1
ps2pdf blank.pdfgibt einen Fehler zurück, da eine Postscript-Datei als Argument erwartet wird. Und der zweite Befehl setzt voraus, dass er bereits vorhanden ist file.pdf. Vermisse ich etwas?
Faheem Mitha
1
Versuchen Sie dies: 1 touch blank.ps.; 2 ps2pdf blank.ps blank.pdf.; 3.pdftk A=1.pdf B=blank.pdf cat A1-end B output 2.pdf
Victoria Stuart
2

Zu guter Letzt können Sie mit Ghostscript eine PDF-Datei mit einer leeren Seite erstellen:

 gs -sDEVICE=pdfwrite -o empty.pdf -c showpage

Die Seitengröße wird höchstwahrscheinlich Letter sein. Wenn Sie A4 möchten, verwenden Sie Folgendes:

 gs -sDEVICE=pdfwrite -o empty.pdf -g5950x8420 -c showpage

Hintergrund: Auf den -cParameter kann eine beliebige gültige PostScript-Zeichenfolge folgen, die Ghostscript zu interpretieren versucht. Und eine leere Seite in PostScript wird durch diesen kurzen Codeblock dargestellt:

%!PS
showpage
Kurt Pfeifle
quelle