Technology
I ran three PDFs through Ghostscript's /screen, /ebook and /printer presets. Here's what happened to each.
Source: Dev Community|
3 min read
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 1. /screen was not the smallest for the photo. /screen downsampled the photo to 720 × 480 px (72 dpi) but stored it with lossless Flate compression. /ebook kept 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 /screen always wins. 2. The scan barely moved on /ebook and /printer. Only /screen made a real difference (15% of the original). At 200 dpi, the scan was already close to what the other two presets aim for. 3. A text-only PDF can grow. /printer doubled 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 /ebook too. 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.