102

I recently needed a single blank PDF page (8.5" x 11" size) and realized that I didn't know how to make one from the command line.

Issuing touch blank.pdf produces an empty PDF file. Is there a command line tool that produces an empty PDF page?

Anko
  • 4,526
  • 1
    Why do you need it? I have a printing package for emulating two-sided (duplex) printing on non-duplex printers. Doing this requires putting out an extra blank page when printing the even numbered pages for a job that has an odd page count. To do this, I just send a formfeed to lp. That does the trick without creating a blank page file, etc.. – Joe Apr 22 '16 at 20:21
  • 15
    @Joe It's none of our business why Brian wants or needs this. – Iain Holder Apr 23 '16 at 16:22
  • 8
    @IainHolder: I wish more SE users thought like you. – user541686 Apr 24 '16 at 05:34
  • 7
    @IainHolder - I'm not trying to pry into the OP's business! I just wanted to suggest that if it's something like what I was doing, then there's another way to do it. Often things like this are xy problems (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem), so asking what the goal is can be quite appropriate. – Joe Apr 24 '16 at 23:27
  • 6
    I just read through the link above in detail. I didn't realize this was such a controversial issue. TL;DR - if you know what you're doing, then you just want the answer to the question you asked. If you're not so well versed, you may have asked the wrong question and clarification of what the real issue is could help. – Joe Apr 24 '16 at 23:50

11 Answers11

132

convert, the ImageMagick utility used in Ketan's answer, also allows you to write something like

convert xc:none -page Letter a.pdf

or

convert xc:none -page A4 a.pdf

or (for horizontal A4 paper)

convert xc:none -page 842x595 a.pdf

etc., without creating an empty text file. @chbrown noticed that this creates a smaller pdf file.

"xc:" means "X Constant Image" but could really be thought of as "x canvas". It's a way to specify a single block of a color, in this case none. More info at http://imagemagick.org/Usage/canvas/#solid which is the "de facto" manual for ImageMagick. [supplemented with information from pipe] (Things like pdf:a can be used to explicitly declare the format of a file. label:'some text', gradient:, rose: and logo: seem to be other examples of special file formats.)

Anko suggested posting this modification as a separate answer, so I am doing it.

psmears
  • 465
  • 3
  • 8
BartekChom
  • 1,328
  • 3
    ImageMagick does not really have a useful manual. "xc:" means "X Constant Image" but could really be thought of as "x canvas". It's a way to specify a single block of a color, in this case none. More info at http://www.imagemagick.org/Usage/canvas/#solid which is the "de facto" manual for ImageMagick. – pipe Apr 21 '16 at 07:29
  • 2
    As a by-the-way, this also works with A4 instead of Letter, if you want sensible paper sizes. – TRiG Apr 21 '16 at 11:30
  • @TRiG: Of course. I am sorry that I did not mention you in my edit, but in this case I had known it. – BartekChom Apr 21 '16 at 12:44
  • I changed this to the accepted answer since it's the one I put into my ~/bin – Brian Fitzpatrick Apr 21 '16 at 20:42
  • Can this command be altered to produce a pdf file with n blank pages? – Brian Fitzpatrick Dec 13 '17 at 20:03
  • 7
    When running this command I got an error convert-im6.q16: not authorized 'blank.pdf' @ error/constitute.c/WriteImage/1037, but I found the solution here: https://askubuntu.com/questions/1081895/trouble-with-batch-conversion-of-png-to-pdf-using-convert Posting here in case it helps anyone else who runs into the same issue. – Brent Yorgey Apr 11 '19 at 14:54
  • @BartekChom Is it possible to create a file with multiple pages? Say 20 pages... Thanks. – Dox May 26 '21 at 20:08
  • Note that while ImageMagick's geometry argument accepts decimal values, they are rounded to next whole number before they are written to the PDF file which can result in incorrect page sizes. This can be inspected with pdfinfo from poppler. – Stefan Schmidt Jun 09 '23 at 23:59
46

Like the smallest possible GIF, the smallest possible blank-page PDF needs to be worked out by hand, because it's so small that unnecessary-but-harmless bits of metadata become a significant part of the file size, and compression actually makes things bigger. It also requires careful attention to the rules in the PDF specification about what bits of the file structure are and are not required. (Did you know that page objects must contain a /Resources dictionary, even if it's empty, but are not required to include a /Contents stream?)

If you don't use PDF 1.5 object and cross-reference streams (which has the advantage that the file can be completely printable ASCII) I believe the best you can do is 317 bytes. If copying and pasting, take note that there needs to be a trailing space on all four of the cross-reference table entries (the lines between 0 4 and trailer<<...), and that there is not supposed to be a final newline after the %%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

Replacing the cross-reference table with a manually crafted v1.5 cross-reference stream does make the file slightly smaller, at the price of its no longer being printable ASCII: 294 bytes. (For the sake of readability, not to mention being able to type it in at all, the xref stream below has been hexdumped, but this is not reflected in its stream dictionary. To recover a valid PDF you must either replace the hexdump with the corresponding raw binary bytes, or change /Length 15 to /Length 30/Filter/ASCIIHexDecode and accept a file that is 328 bytes long.)

%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

I also experimented with wrapping objects 1 through 3 into an object stream, but this adds back more overhead than it saves, even when the stream is compressed.

A possible alternative formulation of the xref stream is

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

Sadly, despite the substantial savings in the length of the actual stream data, the additional /Index[1 4] eats up all but one byte of the savings. Also, it is unclear to me whether you're allowed to leave object 0 completely out of the file. (It's also unclear to me whether object 0 must have generation number -1. If that's not required, you actually save more bytes with

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

.)

To change the paper size, replace 612 792 with the appropriate width and height, expressed in PostScript points (72 PostScript points = 1 U.S. inch or 25.4 millimeters). For instance, 595 842 for A4. You could embed this in a shell script that spits out a blank PDF of whatever paper size is desired; the only tricky part would be making sure that the startxref offset remained accurate even if the size of object 3 changed.

zwol
  • 7,177
  • 11
    This might be a fun activity for http://codegolf.stackexchange.com – Nate Eldredge Apr 21 '16 at 02:50
  • 5
    I posted to meta.codegolf to see if something like this would be well received: http://meta.codegolf.stackexchange.com/questions/8990/hand-crafting-a-pdf – Nate Eldredge Apr 21 '16 at 03:03
  • 1
    While this is a nice solution to create a valid PDF document with an empty page in a *text editor* it's not exactly what I regard a *commandline solution* (as the OP asked for). – Kurt Pfeifle Oct 15 '19 at 09:46
  • 1
    Great answer. Note you can echo this: echo -n "%PDF-1.4..." > blank.pdf – joematune Sep 07 '23 at 18:18
24

If you have convert (an ImageMagick utility) installed, you could do this:

touch a.txt && convert a.txt -page Letter a.pdf
Ketan
  • 9,226
  • 1
    convert also has a -size option which you can use to set size of the output pdf. – Ketan Apr 20 '16 at 18:53
  • 23
    You can also write convert xc:none -page Letter a.pdf without creating empty txt file. – BartekChom Apr 20 '16 at 19:34
  • 3
    @BartekChom's method seems to create an even blanker blank page. It produces a smaller file, with absolutely nothing selectable on it, and it doesn't trigger any (null) font errors. – chbrown Apr 20 '16 at 22:13
  • 1
    @BartekChom I want that as a separate answer so I can upvote it. – Anko Apr 21 '16 at 00:17
  • 1
    I got convert.im6: improper image headera.txt' @ error/txt.c/ReadTXTImage/429. convert.im6: no images defined a.pdf' @ error/convert.c/ConvertImageCommand/3044. – Sigur Jun 20 '16 at 17:02
  • Works for me with ImageMagick version: 6.7.2-7 2015-07-22 Q16 – Ketan Jun 20 '16 at 17:39
19

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

Brought to you by groff, the world's most underrated software.

  • 4
    I get groff: can't find \DESC' fileandgroff:fatal error: invalid device `pdf'` with groff version 1.22.2 on CentOS 7.2. – gla3dr Apr 21 '16 at 16:18
  • Same message for me using bash 4.1.2 running groff 1.18.1.4 – zundarz Apr 21 '16 at 18:17
  • 2
    @gla3dr Install the complete groff package not just groff-base. – Captain Giraffe Apr 21 '16 at 18:33
  • 4
    .bp just stands for "break page", which is why this produces a 2 page document. To produce a 1 page document, just do the even simpler echo | groff -T pdf > blank.pdf. – Faheem Mitha Jun 17 '17 at 03:07
  • very nice solution, but echo .bp should indeed be replaced by echo, just like @FaheemMitha said – myrdd Apr 02 '19 at 13:02
  • example could also be expanded: echo -e "Hello\n.bp\nWorld!" | groff -T pdf > hello.pdf. But I agree that question asks for a blank page, so echo | groff -T pdf > blank.pdf fits best. – Boris Däppen Sep 12 '19 at 09:28
14

You could use pdfTeX:

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

which produces a blank single-page texput.pdf of about 900 bytes, half of what ImageMagick uses.

This puts you at the mercy of the paper size default of your TeX installation, though. To set the size explicitly you can go to LaTeX instead:

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

Yet another option would be to use Ghostscript's PDF driver, though the handy ps2pdf script:

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

which is much quieter than TeX but produces less compact output (about 2300 bytes).

  • 1
    I use the variant echo "" | ps2pdf -sPAPERSIZE=a4 - blank.pdf. This is slightly smaller, at 2200 bytes. – Faheem Mitha Apr 22 '16 at 10:59
  • echo '\documentclass[letterpaper]{article}\usepackage[pass]{geometry} \begin{document}\shipout\hbox{}\end{document}' | pdflatex creates article.pdf. Is it possible to have it create blank.pdf directly? – Faheem Mitha Apr 22 '16 at 11:05
  • @FaheemMitha: Hmm, I would expect ps2pdf with an empty input to produce a PDF file containing zero pages -- but when I try there is indeed a page there. Wonder where that comes from ... – hmakholm left over Monica Apr 22 '16 at 11:12
  • @Faheem: With Texlive at least, you can set the basename of the output file with -jobname <basename> on the command line. – hmakholm left over Monica Apr 22 '16 at 11:16
  • Ah, yes, -jobname. That's the correct argument to pass to pdflatex. – Faheem Mitha Apr 22 '16 at 11:38
  • What's the simplest way to modify these commands to produce a PDF with n pages for arbitrary n? – Faheem Mitha Jun 17 '17 at 02:47
  • 1
    @FaheemMitha: Each \shipout\hbox{} or showpage produces one page. Both TeX and Postscript have looping constructs you could use, but it is probably simpler to use the scripting language of your choice to duplicate the command an appropriate number of times. – hmakholm left over Monica Jun 17 '17 at 08:52
5

On the command line, you can also use the command ps2pdf to convert a PostScript file to PDF; for instance:

touch blank.ps && ps2pdf blank.ps blank.pdf
Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
GAD3R
  • 66,769
5

If you care about efficiency, I advice to use mutool.

mutool create -o empty.pdf /dev/null

This generates a pdf file with an empty A4 (595 x 842 pts) page. To get letter size (792 x 612 pts), use

mutool create -o empty.pdf <(echo "%%MediaBox 0 0 792 612")

Frankly, efficiency might not matter in this particular case, but it is notable that mutool seems to offer better efficiency than any other tool mentioned here. This may be relevant in production contexts.

Benchmark

We iterated each command 1000 times and got the following results.

Rank tool (package) time (efficiency) output file (A4) file size PDF version
1 mutool (MuPDF v1.18) 0m7.850s empty-mutool.pdf 470 bytes 1.7
2 convert (ImageMagick v7.1) 0m10.416s empty-convert.pdf 1912 bytes 1.4
3 pdftex (texlive-pdftex-bin vπ-2.6) 1m3.898s empty-pdftex.pdf 934 bytes 1.5
4 groff (groff/gropdf v1.22.4) 1m58.505s empty-groff.pdf 808 bytes 1.4
5 ps2pdf (ghostscript v9.54) 2m20.843s empty-ps2pdf.pdf 2254 bytes 1.4
#!/bin/bash
LIMIT=1000
echo -n "convert (imagemagick) "
time for I in $(seq ${LIMIT}); do
convert xc:none -page A4 empty-convert.pdf && echo -n "." || exit 1
done && echo -e "==[OK]==\n"

echo -n "mutool (mupdf) " time for I in $(seq ${LIMIT}); do mutool create -O decompress -o empty-mutool.pdf /dev/null && echo -n "." || exit 1 done && echo -e "==[OK]==\n"

echo -n "groff " time for I in $(seq ${LIMIT}); do echo | groff -T pdf > empty-groff.pdf && echo -n "." || exit 1 done && echo -e "==[OK]==\n"

echo -n "pdftex (texlive-pdftex-bin) " time for I in $(seq ${LIMIT}); do echo '\shipout\hbox{}\end' | pdftex -jobname empty-pdftex 1> /dev/null && echo -n "." || exit 1 done && echo -e "==[OK]==\n" rm empty-pdftex.log # be careful

echo -n "ps2pdf (ghostscript) " time for I in $(seq ${LIMIT}); do echo | ps2pdf -sPAPERSIZE=a4 - empty-ps2pdf.pdf && echo -n "." || exit 1 done && echo -e "==[OK]==\n"

  • Nice work on the timing and size comparisons. With mutool version 1.17.0 I get PDF version 1.4, though. OK, I see you are using 1.18. – Faheem Mitha Aug 01 '23 at 03:37
4

Last, not least, here is the Ghostscript way to create a PDF showing an empty page:

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

The page size will most likely be Letter. If you want A4, use this:

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

Background: the -c parameter can be followed by any valid PostScript string, which Ghostscript will try to interpret. And an empty page in PostScript is represented by this short code block:

%!PS
showpage
Kurt Pfeifle
  • 1,461
3

An easy way to make a PDF with a blank page, is using rst2pdf:

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

just echoing in a single space will not do, you'll end up with a PDF file without pages (which is not the same as an empty file).

Anthon
  • 79,293
1

This will produce a PDF file of 1 blank page:

gs -sDEVICE=pdfwrite -o emptyOnePage.pdf -dDEVICEWIDTHPOINTS=612 -dDEVICEHEIGHTPOINTS=792 -c 1 {showpage} repeat

Change the 1 to any larger number to produce more pages.

This will produce a PDF file of 64 numbered pages:

gs -sDEVICE=pdfwrite -o NumberPages64.pdf -dDEVICEWIDTHPOINTS=612 -dDEVICEHEIGHTPOINTS=792 -c "/Times-Roman findfont 32 scalefont setfont /pagenum 0 def 64 {newpath 250 50 moveto (page ) /pagenum pagenum 1 add def show pagenum ( ) cvs show showpage} repeat"

Change the 64 to however many pages you want (1 works, too). 1000000 worked when I tried it - but I did not open that output in a document viewer!

Rob Tow
  • 11
  • 3
1

With qpdf

qpdf -empty -- vide.pdf

result file size is 315 bytes