Skip to content

Instantly share code, notes, and snippets.

@ip413
Last active December 8, 2016 15:10
Show Gist options
  • Save ip413/dc3d9cb2c1e12fd16a4644a3cd7a4da8 to your computer and use it in GitHub Desktop.
Save ip413/dc3d9cb2c1e12fd16a4644a3cd7a4da8 to your computer and use it in GitHub Desktop.
Bash script for recursive compress of jpg files
#!/bin/bash
if [ -z "$1" ] || [ -z "$2" ]
then echo "
Usage: script [directory] [quality] [change files]
Requirements: ImageMagic (convert, identify), jpegoptim
Arguments:
directory - script take all jpg files from directory
quality - jpg quality value (0-100); if file has higher quality will be processed lossy, otherwise lossless
additional options (optional)
change files - if true files will be changed, otherwise (default) then will not change any files (test run)
Script flow:
- find all jpg|jpeg|JPG|JPEG files in \"directory\"
- if file has quality higher than argument \"quality\" convert it to target quality
- if file has size lower than 10KB use non progressive option (better result for final file size)
- if file has size bigger than 10KB use progressive option
- optimize image
Default options for jpegoptim are: p,s
p - preserve file timestamp
s - strip all markers (xmp, iptc etc.)
Example:
./compress-jpg.sh img-test/ 93 -n
"
else
# Progressive option is inefficient for small images; that is "normal" will make smaller files
PROGRESSIVE_THRESHOLD=10240
dirName=$1
qualityThreshold=$2
# changeFiles=$3
changeFiles=$3
startDirSize=$(du -s $dirName | cut -f 1)
# Removing possible error.log without errors
touch error.log && rm error.log
find $dirName -type f \( -iname \*.jpg -o -iname \*.jpeg \) | while read file; do
echo "----------"
fileQuality=$(($(identify -verbose "$file" | grep 'Quality:' | sed 's/[^0-9]//g')))
fileSize=$(stat --printf="%s" "$file")
# File conversion should be before checking progressive option, because conversion changes file size.
optionQuality=" "
if (($fileQuality > $qualityThreshold)) && [[ $changeFiles == true ]]; then
# Convert (imageMagic) use much better quality in lossy compression, so we don't using jpegoptim to this, although
# it can do it.
convert -quality $qualityThreshold "$file" "$file"
fi
optionProgressive=" "
if (($fileSize > $PROGRESSIVE_THRESHOLD)); then
optionProgressive="--all-progressive"
else
optionProgressive="--all-normal"
fi
if [[ $changeFiles == true ]]; then
jpegoptimNoAction=""
else
jpegoptimNoAction="-n "
fi
command="jpegoptim -p -s $optionQuality $optionProgressive $jpegoptimNoAction \"$file\""
echo $command
eval $command 2>> error.log
done;
echo "=========="
endSize=$(du -s $dirName | cut -f 1)
diffSize=$(($startDirSize - $endSize))
diffPercent=$(($(($diffSize*100))/$startDirSize));
echo "Saved $diffSize KB ($diffPercent%)"
if [ -s error.log ]; then
printf "Errors:\n" && cat error.log
else
rm error.log 2> /dev/null
fi
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment