-
Notifications
You must be signed in to change notification settings - Fork 4
/
compressLossy.sh
executable file
·181 lines (149 loc) · 6.37 KB
/
compressLossy.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#!/bin/sh
# Copyright 2013 - 2015 Bruce Ingalls
# MIT license, similar to GraphicsMagick & ImageMagick:
# http://opensource.org/licenses/MIT http://www.graphicsmagick.org/Copyright.html
GM=`which gm` > /dev/null 2>&1 #GM blank for ImageMagick
if [ $# -gt 0 ]; then
echo "Usage: `basename $0` [no args | -h This help]"
echo 'Lossless & lossy compresses all *.gif, *.jpg, *.png in a directory.'
echo 'Compares as many CLI F/OSS tools as possible, with singular goal of smallest lossless compression'
echo 'Then, GraphicsMagick creates a "compressed" folder, with lossy copies of images'
echo 'See also the source code, for tunable parameters. Any suggested installs follow - '
if [ -z $GM ]; then # convert is the ImageMagick tool
which convert >/dev/null || (echo 'Please install GraphicsMagick or ImageMagick!'; exit)
fi
#Lossless gif
which gifsicle >/dev/null || echo 'gifsicle recommended' # fast, but limited results?
#Lossless jpg
which jpegoptim >/dev/null || echo 'jpegoptim recommended'
which jpegrescan >/dev/null || echo 'jpegrescan recommended'
#Lossless png
which optipng >/dev/null || 'optipng recommended'
which pngcrush >/dev/null || echo 'pngcrush recommended'
which pngnq >/dev/null || echo 'pngnq recommended'
#Lossy png
#Disabled: not clear, that pngquant compresses better than *magick.
#which pngquant || echo 'Install pngquant for greater compression'
exit
fi
# USER TUNED VALUES
COMPRESS_DIR='./compressed' # Lossy compressed copies go in $COMPRESS_DIR.
RATIO='40' # Percent compression. I recommend a range of 40%(small) - 75%(quality)
TRANSPARENT_RATIO='05' # png only; compression ratio of transparent background
# END USER TUNED VALUES
# graphicsmagick (faster alternative, but fewer unused features? than imagemagick)
# imagemagick
# gif2png # Copies *.gif into unanimated *.png files
# gifsicle
# jpegoptim
# jpegrescan
# optipng
# pngcrush
# pngnq # seems better than pngquant
# Not impressed with compression of :
# pngquant; uncomment yourself
# giflossy too lazy to install
# GraphicsMagick seems to outperform ImageMagick
# ToDo: handle -sampling-factor and filter-type
# ToDo: Handle 2-step gif optimization, where 2nd pass compresses better
# http://www.graphicsmagick.org/GraphicsMagick.html#details-quality
# See also lossless http://www.smushit.com/ysmush.it/
# GraphicsMagick & ImageMagick only handle .jpg & .png, and limited .gif
CWD=`pwd`
#Create dest dir for compressed copies of images
if [ ! -d $COMPRESS_DIR ];then
mkdir $COMPRESS_DIR
else
#read -t15 is bash for timeout of 15 seconds
read -p "$COMPRESS_DIR/ already exists. 'y' to overwrite existing files: " proceed
if [ "y" != $proceed ];then
echo "Exiting, to preserve existing contents in ./$COMPRESS_DIR/"
exit 1;
fi
fi
# Assumes images follow standard naming convention of *.gif, *.jpg, *.png
# Does anyone use *.jpeg ?
# Remember to wrap "$i", "$file", "$smallest" for filenames with spaces
if [ `find . -maxdepth 1 -name "*.jpg" | head -1` ]; then # *.jpg exists
for i in *.jpg;do
if [ `which jpegoptim` ]; then jpegoptim "$i" ;fi # also supports lossy flag
file=`basename "$i"`
if [ `which jpegrescan` ]; then
jpegrescan -s "$i" $COMPRESS_DIR/"$file"
smallest=`ls -S "$file" $COMPRESS_DIR/"$file"|tail -1`
if [ "$smallest" = $COMPRESS_DIR/"$file" ];then
mv -f "$smallest" "$file"
else
rm -f $COMPRESS_DIR/"$file"
fi
fi
cp "$i" $COMPRESS_DIR/tmp_"$file"
$GM convert $COMPRESS_DIR/tmp_"$file" -quality $RATIO $COMPRESS_DIR/tmp_lossy.jpg
smallest=`ls -S $COMPRESS_DIR/tmp_*|tail -1`
if [ "$smallest" = "$COMPRESS_DIR/tmp_lossy.jpg" ];then
mv -f "$smallest" $COMPRESS_DIR/"$file"
fi
rm $COMPRESS_DIR/tmp_*
done
fi # *.jpg exists
# GraphicsMagick can't compress gif files. Create unanimated png, if smaller
if [ `find . -maxdepth 1 -name "*.gif" | head -1` ]; then # *.gif exists
for i in *.gif;do
if [ `which gifsicle` ]; then gifsicle -b -O3 "$i" ;fi # fast, but limited results
file=`basename "$i" .gif`
cp "$i" $COMPRESS_DIR/tmp_"$file".gif
$GM convert "$i" $COMPRESS_DIR/tmp_lossless.png
# png calls syntax of transparent 0 main_image ratio; ex quality 30% 51%
if [ -f "$COMPRESS_DIR/tmp_lossless.png" ];then
#echo "Converting "$i" to png!"
$GM convert $COMPRESS_DIR/tmp_lossless.png -quality \
"$TRANSPARENT_RATIO0$RATIO" $COMPRESS_DIR/tmp_lossy.png
smallest=`ls -S $COMPRESS_DIR/tmp_*|tail -1` # compare file size
if [ `echo "$smallest" | egrep '.png$'` ];then
mv -f "$smallest" $COMPRESS_DIR/"$file".png
cd $COMPRESS_DIR
rm -f "$file".gif
ln -s "$file".png "$file".gif
cd $CWD
fi
else
echo "Could not convert $i to png!"
fi
rm $COMPRESS_DIR/tmp_*
done
fi # *.gif exists
if [ `find . -maxdepth 1 -name "*.png" | head -1` ]; then # *.png exists
mkdir $COMPRESS_DIR/tmp
for i in *.png;do
# Optipng only replaces original, if smaller.
if [ `which optipng` ]; then optipng -quiet -o2 "$i" ;fi
#More pngcrush options to hack & benchmark. Pngcrush cannot replace self.
if [ `which pngcrush` ]; then pngcrush -q "$i" $COMPRESS_DIR/tmp/crush.png ;fi
#if [ `which pngcrush` ]; then pngcrush -q -l9 -m0 "$i" $COMPRESS_DIR/tmp/crush.png ;fi
file=`basename "$i"`
if [ `which pngnq` ]; then
pngnq -e '.png' -d $COMPRESS_DIR "$i"
smallest=`ls -S "$file" $COMPRESS_DIR/"$file"|tail -1`
if [ "$smallest" = $COMPRESS_DIR/"$file" ];then
mv -f "$smallest" "$file"
else
rm -f $COMPRESS_DIR/"$file"
fi
fi
#png calls syntax of transparent 0 main_image ratio; ex quality 30% 51%
$GM convert "$i" -quality "$TRANSPARENT_RATIO0$RATIO" $COMPRESS_DIR/tmp/magick.png
smallest=`ls -1S $COMPRESS_DIR/tmp/*|tail -1`
if [ `uname` = 'Darwin' ]; then
if [ `du -k "$smallest"|cut -f1` -lt `du -k "$i"|cut -f1` ];then # Mac OSX does not support bytes :(
mv -f "$smallest" $COMPRESS_DIR/"$file"
fi
else
if [ `du -b "$smallest"|cut -f1` -lt `du -b "$i"|cut -f1` ];then # Assume Linux, which can compare bytes
mv -f "$smallest" $COMPRESS_DIR/"$file"
fi
fi
#Insert a read here, to pause, and compare *magick to pngcrush, for benchmarking.
rm $COMPRESS_DIR/tmp/*
done
rmdir $COMPRESS_DIR/tmp
fi # *.png exists