How to make PDF smaller
I recently had to shrink some PDF files to send to be able send them by email.
Shrinking a PDF
gs -q -sDEVICE=pdfwrite -dCompatibilityLevel=1.7 -dPDFSETTINGS=/ebook -dNOPAUSE -dBATCH -sOutputFile=out.pdf in.pdf
Let's break is down !
gs
stands for Ghostscript, a suite of tools for Ghostscript and PDF files, whose primary purpose is rendering PDF.
First, we run it in silence mode using -q
, suppressing normal startup messages.
As Ghostscript can output its result in a wide variety of file format (called output device), we use -sDEVICE=pdfwrite
to specify we want to write a PDF file.
After, we specify the compatibility level we desire. Indeed the PDF format gains new feature as new revisions come out.
Given that PDF
has been an ISO standard since 2008 (with the PDF 1.7 revision), and is the baseline version every reader supports.
Hence it is safe to use that level for our output file.
The next option, -dPDFSETTINGS
selects one of the presets configuration for the conversion process. Available options are:
\screen
: lowest quality, smaller size (72 dpi)\ebook
: medium-quality, medium size (150 dpi)\printer
,\prepress
: highest-quality, biggest size (300 dpi)
The exact content of each preset can be found here
Finally, we prevent the interpreter from entering interactive mode with -dBATCH -dNOPAUSE
once it is done processing the file given from the command line.
Otherwise, it would wait for some input from the keyboard.
In my case, I was able to shrink a file from 45 MB to 6 Mb ! The output was a tiny tiny little bit fuzzy, but still totally legible.
Integrating it in the shell
The command by itself is nice, but it can be annoying to specify the input and output names. To avoid that, we will turn the command into a ZSH function that takes a file, and produces a "file-smaller.pdf" in the same folder.
ZSH has a set of modifiers for retrieving parts of a path inside a variable.
The path can be retrieved appending :h
to it, and the file name without its extensions by combining :t:r
, such that the full command is
function shrink-pdf() {
d=$1:h
name=$1:t:r
gs -q -sDEVICE=pdfwrite -dCompatibilityLevel=1.7 -dPDFSETTINGS=/ebook -dNOPAUSE -dBATCH -sOutputFile=$d/smaller-$name.pdf $1
}