-
-
Save LiamKarlMitchell/10b96093391792efc2cb6bb7f5c5fbf4 to your computer and use it in GitHub Desktop.
Optimize Images sh script. Original: http://hugogiraudel.com/2013/07/29/optimizing-with-bash/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Note, apt-get on Ubuntu seems to be providing an out of date optipng. | |
# Try doing this to install version 0.7.6 | |
# Run optipng -v to see the version you have installed. | |
# wget http://downloads.sourceforge.net/project/optipng/OptiPNG/optipng-0.7.6/optipng-0.7.6.tar.gz | |
# tar xvf optipng-0.7.6.tar.gz | |
# cd optipng-0.7.6 | |
# ./configure | |
# make | |
# sudo cp /src/optipng/optipng /usr/local/bin/optipng | |
# optipng -v | |
PROGNAME=${0##*/} | |
INPUT='' | |
QUIET='0' | |
NOSTATS='0' | |
RETAINPATH='0' | |
max_input_size=0 | |
max_output_size=0 | |
usage() | |
{ | |
cat <<EO | |
Usage: $PROGNAME [options] | |
Script to optimize JPG and PNG images in a directory. | |
Options: | |
EO | |
cat <<EO | column -s\& -t | |
-h, --help & shows this help | |
-q, --quiet & disables output | |
-i, --input [dir] & specify input directory (current directory by default) | |
-o, --output [dir] & specify output directory ("output" by default) | |
-ns, --no-stats & no stats at the end | |
-r, --retain-path & retains the directory structure when writing into output | |
EO | |
} | |
command_exists () { | |
type "$1" &> /dev/null ; | |
} | |
# $1: input image | |
# $2: output image | |
optimize_image() | |
{ | |
input_file_size=$(stat -c%s "$1") | |
max_input_size=$(expr $max_input_size + $input_file_size) | |
if [ "${1##*.}" = "png" ]; then | |
optipng -o2 -clobber -strip all -quiet $1 -out $2 | |
# pngcrush -q -rem alla -reduce -m 7 $2 $2 >/dev/null | |
#pngcrush -rem alla -nofilecheck -reduce -m 7 $2 $2>/dev/null | |
#pngcrush -rem alla -nofilecheck -reduce -m 7 -ow $2 > /dev/null | |
#pngcrush -reduce -brute -ow $2 > /dev/null | |
fi | |
if [ "${1##*.}" = "jpg" -o "${1##*.}" = "jpeg" ]; then | |
jpegtran -copy none -optimize -progressive $1 > $2 | |
fi | |
output_file_size=$(stat -c%s "$2") | |
max_output_size=$(expr $max_output_size + $output_file_size) | |
} | |
get_max_file_length() | |
{ | |
local maxlength=0 | |
IMAGES=$(find $INPUT -regextype posix-extended -regex '.*\.(jpg|jpeg|png)' | grep -v $OUTPUT) | |
for CURRENT_IMAGE in $IMAGES; do | |
filename=$(basename "$CURRENT_IMAGE") | |
if [[ ${#filename} -gt $maxlength ]]; then | |
maxlength=${#filename} | |
fi | |
done | |
echo "$maxlength" | |
} | |
main() | |
{ | |
# If $INPUT is empty, then we use current directory | |
if [[ "$INPUT" == "" ]]; then | |
INPUT=$(pwd) | |
fi | |
# If $OUTPUT is empty, then we use the directory "output" in the current directory | |
if [[ "$OUTPUT" == "" ]]; then | |
OUTPUT=$(pwd)/output | |
fi | |
# We create the output directory | |
mkdir -p $OUTPUT | |
# To avoid some troubles with filename with spaces, we store the current IFS (Internal File Separator)... | |
SAVEIFS=$IFS | |
# ...and we set a new one | |
IFS=$(echo -en "\n\b") | |
max_filelength=`get_max_file_length` | |
pad=$(printf '%0.1s' "."{1..600}) | |
sDone=' [ DONE ]' | |
linelength=$(expr $max_filelength + ${#sDone} + 5) | |
# Search of all jpg/jpeg/png in $INPUT | |
# We remove images from $OUTPUT if $OUTPUT is a subdirectory of $INPUT | |
IMAGES=$(find $INPUT -regextype posix-extended -regex '.*\.(jpg|jpeg|png)' | grep -v $OUTPUT) | |
if [ "$QUIET" == "0" ]; then | |
echo --- Optimizing $INPUT --- | |
echo | |
fi | |
for CURRENT_IMAGE in $IMAGES; do | |
filename=$(basename $CURRENT_IMAGE) | |
if [ "$QUIET" == "0" ]; then | |
printf '%s ' "$filename" | |
printf '%*.*s' 0 $((linelength - ${#filename} - ${#sDone} )) "$pad" | |
fi | |
INPUTABS=$(readlink -f $INPUT) | |
# If we want to retain the directory path. | |
if [ "$RETAINPATH" == "1" ]; then | |
# Create a replica of the absolute path in the output directory. | |
abspath=$(readlink -f $CURRENT_IMAGE) | |
absdirname=$(dirname $abspath) | |
trimmeddir=${absdirname#$INPUTABS} | |
mkdir -p $OUTPUT$trimmeddir | |
# Optimize the image. | |
optimize_image $CURRENT_IMAGE $OUTPUT/$trimmeddir/$filename | |
else | |
# Optimize the image. | |
optimize_image $CURRENT_IMAGE $OUTPUT/$filename | |
fi | |
if [ "$QUIET" == "0" ]; then | |
printf '%s\n' "$sDone" | |
fi | |
done | |
# we restore the saved IFS | |
IFS=$SAVEIFS | |
if [ "$NOSTATS" == "0" -a "$QUIET" == "0" ]; then | |
echo | |
echo "Input: " $(human_readable_filesize $max_input_size) | |
echo "Output: " $(human_readable_filesize $max_output_size) | |
space_saved=$(expr $max_input_size - $max_output_size) | |
echo "Space save: " $(human_readable_filesize $space_saved) | |
fi | |
} | |
human_readable_filesize() | |
{ | |
echo -n $1 | awk 'function human(x) { | |
s=" b Kb Mb Gb Tb" | |
while (x>=1024 && length(s)>1) | |
{x/=1024; s=substr(s,4)} | |
s=substr(s,1,4) | |
xf=(s==" b ")?"%5d ":"%.2f" | |
return sprintf( xf"%s", x, s) | |
} | |
{gsub(/^[0-9]+/, human($1)); print}' | |
} | |
SHORTOPTS="h,i:,o:,q,s,r" | |
LONGOPTS="help,input:,output:,quiet,no-stats,retain-path" | |
ARGS=$(getopt -s bash --options $SHORTOPTS --longoptions $LONGOPTS --name $PROGNAME -- "$@") | |
eval set -- "$ARGS" | |
while true; do | |
case $1 in | |
-h|--help) | |
usage | |
exit 0 | |
;; | |
-i|--input) | |
shift | |
INPUT=$1 | |
;; | |
-o|--output) | |
shift | |
OUTPUT=$1 | |
;; | |
-q|--quiet) | |
QUIET='1' | |
;; | |
-s|--no-stats) | |
NOSTATS='1' | |
;; | |
-r|--retain-path) | |
RETAINPATH='1' | |
;; | |
--) | |
shift | |
break | |
;; | |
*) | |
shift | |
break | |
;; | |
esac | |
shift | |
done | |
if ! command_exists optipng ; then | |
echo "Please install optipng."; | |
exit; | |
fi | |
# if ! command_exists pngcrush ; then | |
# echo "Please install pngcrush."; | |
# exit; | |
# fi | |
if ! command_exists jpegtran ; then | |
echo "Please install jpegtran."; | |
exit; | |
fi | |
main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Changes:
Checks if programs are installed.
clobber is not an option for optipng on ubuntu anymore? Removed.
Can retain directory structure when writing files into output with the -r argument.