DEV Community

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

  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

Read on DEV Community ↗ ← Back to News

Comments

No comments yet. Start the discussion.