I feel that the PDFs produced by pdflatex
are too huge. So for example my 50 page book with no illustrations is 500KB. I feel it should be more like 50K or even less. The .tex
files together are just 40KB. Anyone knows why the final PDF is so huge and is there a way to compress it to make smaller?
3 Answers
A common approach is to let Ghostscript (gs
) optimize and compress the PDF after it has been created with pdflatex
.
Ghostscript is installed by most Linux distributions and is easily available for other platforms (Windows as binaries, MacOS via MacPorts). In fact, almost all size-optimizing tools for PDF (save for Acrobat) you can find on the internet, internally use Ghostscript -- so you can as well call it directly.
There is a plethora of options available; I personally use the following:
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.5 -dNOPAUSE -dQUIET -dBATCH -dPrinted=false -sOutputFile=foo-compressed.pdf foo.pdf
I use this mostly for beamer presentations, where it gets me a size reduction of 60–70 percent. (A 10 MiB lecture note becomes 3–4 MiB in size.)
Edit 2020-02-06: Added -dPrinted=false
to preserve Hyperlinks.
Edit 2020-09-10: Changed -dCompatibilityLevel
from 1.4 to 1.5 as pdflatex
outputs PDF 1.5 by default since 2010.
-
2I wonder if you get the same size reduction if you use
\pdfminorversion=5 \pdfcompresslevel=9 \pdfobjcompresslevel=3
, i.e. maximum compression with PDF v1.5. Commented May 25, 2011 at 22:39 -
1@Martin Scharrer: Not really, with my lecture these options give only a size reduction of 110 Bytes 9825306 no-compression.pdf 9825196 pdflatex-compression.pdf 4318774 gs-compression.pdf 4318772 pdflatex-gs-compression.pdf– DanielCommented May 26, 2011 at 11:13
-
2@Martin Scharrer: I get interesting results: By setting
\pdfcompresslevel=0 \pdfobjectcompresslevel=0
the resulting file size gets smaller (even though only a bit: 9630339 instead of 9825196). Piping this result throughgs
gives exactly the same size as piping no-compression.pdf through it:4318772. So the bottom line is that (at least for beamer presentations)gs
reduces the size quite a bit, independently from the choosen pdflatex compression options.– DanielCommented May 26, 2011 at 12:04 -
6
pdfsizeopt
uses this kind of compression throughgs
as one of the tricks it uses to get smaller PDFs (it also uses a whole tonne of other tricks, so it will generally do better thangs
alone). See also this whitepaper on a whole series of techniques for getting smaller PDFs. Commented Jun 6, 2011 at 15:41 -
3Not every PDF feature will survive such
gs
post-treatment, OCGs (PDF Layers) for instance.– AlexGCommented Dec 4, 2014 at 11:13
Here is a revised version of the script above. The basics are unchanged, but it now handles paths and such in a sane manner, automatically copies the new over the old IFF the new file is smaller then the original (and not 0). It also gives some info on space savings. For some unknown reason, running it again can give even smaller output, but usually not by much. The first run gives the big speedup.
For example:
ekl@Taro:~/Documents⟫ optpdf techResume.pdf
Saving 1245351 bytes (now 6% of old)
ekl@Taro:~/Documents⟫ optpdf techResume.pdf
Saving 31 bytes (now 99% of old)
ekl@Taro:~/Documents⟫ optpdf techResume.pdf
Saving 7 bytes (now 99% of old)
ekl@Taro:~/Documents⟫ optpdf techResume.pdf
Didn't make it smaller! Keeping original
It is legal to give it long paths, but it currently doesn't like spaces in your filenames. Sorry. Getting shell scripts to handle this correctly in all instances is a pain, so just don't don't do it.
Here is the code:
#!/bin/bash
#
# optpdf file.pdf
# This script will attempt to optimize the given pdf
file="$1"
filebase="$(basename "$file" .pdf)"
optfile="/tmp/$$-${filebase}_opt.pdf"
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dNOPAUSE -dQUIET -dBATCH \
-sOutputFile="${optfile}" "${file}"
if [ $? == '0' ]; then
optsize=$(stat -c "%s" "${optfile}")
orgsize=$(stat -c "%s" "${file}")
if [ "${optsize}" -eq 0 ]; then
echo "No output! Keeping original"
rm -f "${optfile}"
exit;
fi
if [ ${optsize} -ge ${orgsize} ]; then
echo "Didn't make it smaller! Keeping original"
rm -f "${optfile}"
exit;
fi
bytesSaved=$(expr $orgsize - $optsize)
percent=$(expr $optsize '*' 100 / $orgsize)
echo Saving $bytesSaved bytes \(now ${percent}% of old\)
rm "${file}"
mv "${optfile}" "${file}"
fi
Enjoy!
-
Nice that you output actual numbers. For a text only document of about 40 pages (created by ConTeXt), I get a reduction of only 2% in size; but for a 50 page presentation (again created by ConTeXt with lots of images and colors), I get a 40% reduction in size.– AdityaCommented Sep 2, 2014 at 17:47
-
1I'm not sure why running it again will reduce it in size more. Its a ghostscript issue. But, its usually the first run that does the big lifting. Its safe to run it over and over - I even considered doing a loop to run it until it won't reduce any more. Commented Sep 20, 2014 at 6:49
-
2If you get errors like
stat: illegal option -- c
andline 14: [: : integer expression expected
, you must changestat -c "%s"
intostat -f "%z"
in lines 12 and 13.– JonathanCommented Jun 14, 2015 at 10:26 -
Thanks for that! It shrinked my 50 pages pdflatex document with images to 37% of original size - pdfsizeopt produced a 86% sized file.– orzechowCommented Dec 25, 2015 at 18:43
-
1@EvanLanglois Suggestion: put your very useful script altogether with a permissive license (GPLv2, BSD, MIT or so) on github. Commented Oct 26, 2019 at 18:46
There is a wonderful script to shrink a PDF: https://github.com/pts/pdfsizeopt . I've been using it for years and can recommend it. The main effect is that it compresses the embedded fonts. Very helpfull if a font is large, like Linux Libertine. The script shrinks such a PDF (if no pictures are included) to 10% of the size!
Using it under Windows requires carefull installation to get all the necessary *.dll files.
Once in a while the script quits with an error message. The most frequent reason is that Multivalent has an issue. Simply avoid multivalent with the command pdfsizeopt.py --use-multivalent=false ...
.
Another issue comes up, if you include other PDFs made by pdftex. Sometimes -- especially with Linux Libertine -- the italic letters in the included PDFs get garbled. We can avoid this by adding as first line to the *.tex file: \pdfinclusioncopyfonts=1
.
-
@ Keks Dose. I have a pdf file (18MB) generated by Texify->dvi-pdf, including many .eps figs. I tried to use
pdfsizeopt
you recommended to reduce its volume to be less than 3MB. With the commandline: c:\ pdfsizeopt\pdfsizeopt --use-multivalent=false --do-unify-fonts=false c:\pdfs\manuscript.pdf. It turns out that it only reduces the input-pdf by 1% or so. Can you give me some further advice?– EnterCommented Jul 18, 2015 at 10:20 -
1@lxy Many ways. Obviously: reduce the size of the pics before including them, without that, you won't get far. Use multivalent, instead of
=false
. If available, use Adobe Pro to shrink the size. Commented Jul 18, 2015 at 11:02 -
@ Keks Dose. Thanks! However with
--use-multivalent=true
, cmd gives me errorMultivalent.jar not found
...– EnterCommented Jul 18, 2015 at 11:49 -
@lyx Well, you'll probably have to install it. The correct way depends on your OS. There used to be a manual by the author of pdfsizeopt. Commented Jul 18, 2015 at 22:43
-
I was able to follow the directions perfectly. Problem I had is that my input file was 28 MB, and my output was 27 MB. There appears to way to tailor the output size. Commented Jan 18, 2020 at 16:35
Advanced > PDF Optimizer > Audit space usage