I ran three PDFs through Ghostscript's /screen, /ebook and /printer presets. Here's what happened to each.
If you've wired Ghostscript into a "compress PDF" feature, you've probably reached for -dPDFSETTINGS. I maintain a small open-source file converter (Flask, Ghostscript and LibreOffice; disclosure: it's my project, KuickKonvert). I wanted to know what the three common presets actually do to ordinary files, so I tested them and published the inputs, outputs and script.
The command
Ghostscript 10.02.1, the same options the converter uses:
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen \
-dAutoRotatePages=/None -dNOPAUSE -dQUIET -dBATCH \
-sOutputFile=out.pdf in.pdf
/ebook and /printer were swapped in for /screen.
The three inputs
| Input | Original | /screen | /ebook | /printer |
|---|---|---|---|---|
| One 3000 × 2000 px photo placed at 300 dpi | 1,096.3 KB | 495.3 KB (45.2%) | 58.3 KB (5.3%) | 881.2 KB (80.4%) |
| One-page greyscale scan, A4 at 200 dpi | 915.3 KB | 138.0 KB (15.1%) | 733.7 KB (80.2%) | 736.3 KB (80.4%) |
| Five-page text-only PDF (standard Helvetica, not embedded) | 5.6 KB | 5.5 KB (99.0%) | 5.5 KB (98.9%) | 11.5 KB (206.5%) |
Three things I didn't expect
/screenwas not the smallest for the photo./screendownsampled the photo to 720 × 480 px (72 dpi) but stored it with lossless Flate compression./ebookkept 1500 × 1000 px (150 dpi) but used JPEG, and came out at 58 KB against 495 KB. The photo here is synthetic (generated noise with grain), so a real camera photo may behave differently, but it was enough to stop me assuming/screenalways wins.- The scan barely moved on
/ebookand/printer. Only/screenmade a real difference (15% of the original). At 200 dpi, the scan was already close to what the other two presets aim for. - A text-only PDF can grow.
/printerdoubled the five-page text file. My guess is that it embedded the font, but I haven't confirmed that from the output file, so treat it as a guess.
What I do in the app because of this
After Ghostscript runs, the converter checks two things: that the output has the same number of pages as the input (Ghostscript can exit with code 0 and still write a blank one-page PDF for some damaged files), and that it is actually smaller. If it isn't smaller, the user gets their original file back.
The size check, simplified:
import os, shutil
def keep_smaller(src, out):
if os.path.getsize(out) >= os.path.getsize(src):
shutil.copyfile(src, out) # compression didn't help: return the original
Takeaways
- Look at what is inside the PDF before compressing: images are where the weight is.
- Don't assume the "lowest" preset gives the smallest file; test
/ebooktoo. - Always compare the output with the input, and fall back to the original.
Reproduce it
- Files, results and the script that regenerates everything from fixed seeds (CC BY 4.0): https://doi.org/10.5281/zenodo.24199945
- Converter source (AGPL-3.0): https://github.com/khshahid1970/kuickkonvert
- Limitations: each test uses a few generated files. Other Ghostscript versions and real-world documents will give different numbers.
Comments
No comments yet. Start the discussion.