Skip to content

Instantly share code, notes, and snippets.

@mgoellnitz
Last active March 31, 2025 13:35
Show Gist options
  • Save mgoellnitz/148d1a99ff6ab4e85262bd806fc6970e to your computer and use it in GitHub Desktop.
Save mgoellnitz/148d1a99ff6ab4e85262bd806fc6970e to your computer and use it in GitHub Desktop.
Reduce PDF File Size to still readable and printable State
#!/bin/bash
#
# Copyright 2021-2025 Martin Goellnitz
#
# 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/>.
#
MODIFY=true
usage() {
echo "Usage: $0 [-m] file1 [file2...]" 1>&2
echo "" 1>&2
echo " -m Don't modify file time of target file by a few seconds to slightly mark change" 1>&2
exit 1
}
if [ -z "$(which gs)" ] ; then
echo "To use this functionality, ghostscript must be installed."
exit 1
fi
while getopts "m" opt ; do
case "${opt}" in
m)
MODIFY=
;;
*)
usage
;;
esac
done
shift $((OPTIND-1))
if [ -z "$*" ] ; then
echo "Input filenames missing as parameters"
echo ""
usage
exit 1
fi
while [ ! -z "$*" ] ; do
INFILE="$1"
shift
if [ -f "$INFILE" ] ; then
BASE=$(dirname "$INFILE")/$(basename "$INFILE" .pdf)
ORIGINAL="${BASE}-orig.pdf"
if [ -z "$(uname -v|grep Darwin)" ] ; then
FILETIME=$(stat -c %Y -- "$INFILE")
else
FILETIME=$(stat -t %s -f %m -- "$INFILE")
fi
if [ ! -z "$MODIFY" ] ; then
FILETIME=$(expr 4 + $FILETIME)
fi
mv "$INFILE" "$ORIGINAL"
# -dPDFSETTINGS=/screen
# -dPDFSETTINGS=/prepress
gs -sDEVICE=pdfwrite -dPrinted=false -dCompatibilityLevel=1.4 -dPDFSETTINGS=/ebook -dNOPAUSE -dQUIET -dBATCH -sOutputFile="$INFILE" "$ORIGINAL"
touch --date="$(date -R --date='@'$FILETIME)" "$INFILE"
ORIGSIZE=$(stat -c %s -- "$ORIGINAL")
# NEWSIZE=$(stat -c %s -- "$INFILE")
NEWSIZE=$[ $(stat -c %s -- "$INFILE") * 102 / 100 ]
# echo $INFILE: $ORIGSIZE $NEWSIZE
if [ "$ORIGSIZE" -le "$NEWSIZE" ] ; then
# echo "Compressed file $INFILE would not be smaller"
mv "$ORIGINAL" "$INFILE"
else
echo "$INFILE yields smaller file."
fi
else
echo "$INFILE is not a file. Ignoring."
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment