Widows & Orphans

Some thoughts that fall through

PDF file diet

Every once in a while, I need a smaller version of some bloated PDF in order to distribute it over the web. Looking for a straightforward solution, I stumbled over the nifty shrinkpdf script by Alfred Klomp that just calls gs, which resizes images and does some other optimiziation.
I found Alfred’s script to be a little bit too inflexible for my needs (e. g., it always downsamples the images to 72 dpi, which is often too low), so I extended the script a bit. Here’s the result. I renamed it to pdfshrink and put it under the GPL (just to make explicit this is open source).
 

The script

Grab the script here (the GPL license is here). Make the script executable and put it somewhere in your PATH (yes, this is a UNIX thing, in case you haven’t noticed yet).
The usage is as follows (cf. pdfshrink --help):

pdfshrink filename.pdf [<ratio>]

<ratio> is the image resolution. Valid values are:

  • --drastical or -d (72 dpi)
  • --small or -s (144 dpi)
  • --medium or -m (200 dpi)
  • --high or -h (300 dpi)
  • <any digit> (e. g., 170).

The default ratio is 144 dpi.

The script outputs a resized version of filename.pdf, named filename-shrunk.pdf, in the current directory.

 

A service menu

For the even lazier, I also made a KDE service menu (the “Action” context menus that appear if you click on files of a specific type in Konqueror or Dolphin, the two file managers of the KDE Desktop). Get it here. You need to put this file into ~/.kde4/share/kde4/services/ServiceMenus/ or whereever your distribution has the KDE service files.

 

The code

For the interested, here is the code. I’m not really a coder, so there’s probably room for improvement:
#!/bin/sh
#
# A simple script to reduce PDF file size with gs
# Initial idea and script: Alfred Klomp
# (http://www.alfredklomp.com/programming/shrinkpdf/)
# Enhancements by Juergen Spitzmueller <juergen (at) spitzmueller (dot) org>
#
# Copyright 2010 Juergen Spitzmueller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

#
# --help message
#
HELP () {
    echo "USAGE:"
    echo "pdfshrink filename.pdf [<ratio>]"
    echo "<ratio> is the image resolution. Valid values:"
    echo "* --drastical or -d (72dpi)"
    echo "* --small or -s (144dpi)"
    echo "* --medium or -m (200dpi)"
    echo "* --high or -h (300dpi)"
    echo "* <any digit>"
    echo "The default ratio is 144dpi."
}

#
# Say hello...
#
echo pdfshrink — a simple PDF downsizing script.

#
# Check if we have valid arguments
#
if [ $# -ne 1 -a $# -ne 2 ]; then
    HELP
    exit 1
fi

#
# --help requested
#
if [ $1 == "--help" -o $1 == "-h" ]; then
    HELP
    exit
fi

#
# Set resolution
#
if [ $# -ne 2 ]; then
    RES=144
    echo No image resolution specified. Using default \($RES\).
else
    if [ $2 = "--drastical" -o $2 = "-d" ]; then
        RES=72
    elif [ $2 = "--small" -o $2 = "-s" ]; then
        RES=144
    elif [ $2 = "--medium" -o $2 = "-m" ]; then
        RES=200
    elif [ $2 = "--high" -o $2 = "-h" ]; then
        RES=300
    elif echo $2 | egrep -v "[a-zA-Z,./:]+" ; then
        RES=$2
    else
         echo Invalid argument \"$2\"! Read --help.
         exit 1
    fi
    echo Specified image resolution: $RES.
fi

#
# The actual work
#

# input file
IFILE=$1
# output file (strip extension and append "-shrunk.pdf")
OFILE="${IFILE%.pdf}"-shrunk.pdf

# now call gs
gs	-q -dNOPAUSE -dBATCH -dSAFER \
	-sDEVICE=pdfwrite \
	-dCompatibilityLevel=1.3 \
	-dPDFSETTINGS=/screen \
	-dEmbedAllFonts=true \
	-dSubsetFonts=true \
	-dColorImageDownsampleType=/Bicubic \
	-dColorImageResolution=$RES \
	-dGrayImageDownsampleType=/Bicubic \
	-dGrayImageResolution=$RES \
	-dMonoImageDownsampleType=/Bicubic \
	-dMonoImageResolution=$RES \
	-sOutputFile=$OFILE \
	 $IFILE

if [ $? -ne 0 ]; then
	echo Ghostscript returned an error. Exiting.
	exit 1
fi

echo pdfshrink: DONE!

Leave a comment