How to shrink / compress pdf files?

Question: How to shrink / compress pdf files?

Answer:

There are many different ways to compress / shrink pdf files. Some of them are;

  1. Programmatically
    1. Ghostscript – script sourceA simple wrapper around Ghostscript to shrink PDFs (as in reduce filesize) under Linux. Inspired by some code I found in an OpenOffice Python script (I think). The script feeds a PDF through Ghostscript, which performs lossy recompression by such methods as downsampling the images to 72dpi. The result should be (but not always is) a much smaller file.

      shrinkpdf.sh

      #!/bin/sh
      
      # http://www.alfredklomp.com/programming/shrinkpdf
      # Licensed under the 3-clause BSD license:
      #
      # Copyright (c) 2014, Alfred Klomp
      # All rights reserved.
      #
      # Redistribution and use in source and binary forms, with or without
      # modification, are permitted provided that the following conditions are met:
      # 1. Redistributions of source code must retain the above copyright notice,
      #    this list of conditions and the following disclaimer.
      # 2. Redistributions in binary form must reproduce the above copyright notice,
      #    this list of conditions and the following disclaimer in the documentation
      #    and/or other materials provided with the distribution.
      # 3. Neither the name of the copyright holder nor the names of its contributors
      #    may be used to endorse or promote products derived from this software
      #    without specific prior written permission.
      #
      # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
      # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
      # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
      # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      # POSSIBILITY OF SUCH DAMAGE.
      
      
      shrink ()
      {
      	gs					\
      	  -q -dNOPAUSE -dBATCH -dSAFER		\
      	  -sDEVICE=pdfwrite			\
      	  -dCompatibilityLevel=1.3		\
      	  -dPDFSETTINGS=/screen			\
      	  -dEmbedAllFonts=true			\
      	  -dSubsetFonts=true			\
      	  -dAutoRotatePages=/None		\
      	  -dColorImageDownsampleType=/Bicubic	\
      	  -dColorImageResolution=$3		\
      	  -dGrayImageDownsampleType=/Bicubic	\
      	  -dGrayImageResolution=$3		\
      	  -dMonoImageDownsampleType=/Bicubic	\
      	  -dMonoImageResolution=$3		\
      	  -sOutputFile="$2"			\
      	  "$1"
      }
      
      check_smaller ()
      {
      	# If $1 and $2 are regular files, we can compare file sizes to
      	# see if we succeeded in shrinking. If not, we copy $1 over $2:
      	if [ ! -f "$1" -o ! -f "$2" ]; then
      		return 0;
      	fi
      	ISIZE="$(echo $(wc -c "$1") | cut -f1 -d\ )"
      	OSIZE="$(echo $(wc -c "$2") | cut -f1 -d\ )"
      	if [ "$ISIZE" -lt "$OSIZE" ]; then
      		echo "Input smaller than output, doing straight copy" >&2
      		cp "$1" "$2"
      	fi
      }
      
      usage ()
      {
      	echo "Reduces PDF filesize by lossy recompressing with Ghostscript."
      	echo "Not guaranteed to succeed, but usually works."
      	echo "  Usage: $1 infile [outfile] [resolution_in_dpi]"
      }
      
      IFILE="$1"
      
      # Need an input file:
      if [ -z "$IFILE" ]; then
      	usage "$0"
      	exit 1
      fi
      
      # Output filename defaults to "-" (stdout) unless given:
      if [ ! -z "$2" ]; then
      	OFILE="$2"
      else
      	OFILE="-"
      fi
      
      # Output resolution defaults to 72 unless given:
      if [ ! -z "$3" ]; then
      	res="$3"
      else
      	res="72"
      fi
      
      shrink "$IFILE" "$OFILE" "$res" || exit $?
      
      check_smaller "$IFILE" "$OFILE"
      

      Usage

      Download the script by clicking the filename at the top of the box. Make it executable. If you run it with no arguments, it prints a usage summary. If you run it with a single argument – the name of the pdf to shrink – it writes the result to stdout:

      ./shrinkpdf.sh in.pdf > out.pdf

      You can also provide a second filename for the output:

      ./shrinkpdf.sh in.pdf out.pdf

      And an output resolution in DPI (default is 72 DPI):

      ./shrinkpdf.sh in.pdf out.pdf 90

      If both the input and the output are regular files, the script checks if the output is actually smaller. If not, it writes a message to stderr and copies the input over the output.

      Sorry, Windows users; this one is Linux only. A Windows adaptation of this script can be found on this blog. It’s a bit more user-friendly than my barebones version and also supports drag-and-drop.

About Firat Karakusoglu

IIT Tech.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: