Skip to content

Instantly share code, notes, and snippets.

@tuttle
Created April 2, 2017 12:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tuttle/6ded6256c9e746083df51e267db43f42 to your computer and use it in GitHub Desktop.
Save tuttle/6ded6256c9e746083df51e267db43f42 to your computer and use it in GitHub Desktop.
#!/bin/bash
# stop on first error
#set -e
# match patterns in a case-insensitive fashion when performing matching while executing case or [[
shopt -s nocasematch
RESIZE=""
TRIM=""
ORIENT=""
QUAL=50
COPY_EXIF=""
TGT=""
while getopts "hd:ms:toq:e" OPT; do
case $OPT in
d) TGT="$OPTARG/"
;;
m) [ "$RESIZE" ] && {
echo "$0: Options -m and -s are mutually exclusive." >&2
exit 1
}
RESIZE="2560x1600"
;;
s) [ "$RESIZE" ] && {
echo "$0: Options -m and -s are mutually exclusive." >&2
exit 1
}
RESIZE="$OPTARG"
;;
t) TRIM="-fuzz 20% -trim +repage"
;;
o) ORIENT="-auto-orient"
;;
q) QUAL="$OPTARG"
;;
e) COPY_EXIF=y
;;
h) echo "
optimize-images -- makes your image storage needs more optimistic
Author: Vlada Macek <macek@sandbox.cz>, 2016-2017
The current files are always left intact. First the subdirectory
__optimized... (name followed by short labels of operations) for targets is
created, by default in the current directory.
Images impossible to shrink are hard-linked to target directory, as well as
animated GIFs. Errors are stored in __errors subdirectory.
All processing is done in parallel, spread to the number of CPUs detected by
the nproc command.
Requirements:
'convert' and 'identify' from ImageMagick
mocjpeg in '/opt/mozjpeg/bin/cjpeg' from https://github.com/mozilla/mozjpeg
'exiftool'
Options:
-d PATH - don't create target subdir here, but under PATH
-s WIDTHxHEIGHT - the rectangle in which the resulting image should fit
-m - same as -s 2560x1600
-t - crop out the border of pixels having roughly the same color
around the image
-o - automatically orient image (reads and resets the EXIF image
profile setting 'Orientation')
-q QUALITY - change the default output JPEG quality 50 to QUALITY
-e - use ExifTool to copy the EXIF data to target file, remove
embedded thumbnails
-h - this help
"
exit 1
;;
esac
done
TGT="${TGT}__optimized_q$QUAL"
[ "$RESIZE" ] && {
TGT+="_$RESIZE"
RESIZE="-resize $RESIZE>"
}
[ "$TRIM" ] && TGT+="_trim"
[ "$ORIENT" ] && TGT+="_orient"
[ "$COPY_EXIF" ] && TGT+="_exif"
echo "# Target: $TGT"
ERRS="$TGT/__errors"
[ "$1" ] && mkdir "$TGT" || exit 0
[ "$CPU_NUMBER" ] || CPU_NUMBER="`nproc 2>/dev/null || echo 1`"
CONVERTOR="convert - $ORIENT $TRIM $RESIZE tga:-"
OPTIMIZER="/opt/mozjpeg/bin/cjpeg -targa -optimize -progressive -sample 1x1 -quant-table 2 -quality $QUAL"
while [ "$1" ]; do
# only take non-empty regular files or symlinks
[ -f "$1" -a -s "$1" ] || { shift; continue; }
{
TMPF="/tmp/.optimize-images.tmp.$#.$$"
if [[ $1 =~ \.gif$ && "`identify -ping "$1" | wc -l`" -gt 1 ]]; then
echo "[$# left] $1 - animated GIF, hard-linking original"
ln -f "$1" "$TGT/$1"
else
$CONVERTOR < "$1" | $OPTIMIZER > "$TMPF"
TGT_SIZE="`stat -c %s "$TMPF"`"
if [ "$TGT_SIZE" = 0 -o -z "$TGT_SIZE" ]; then
echo "ERROR, target file is empty or so, hard-linking original to $ERRS."
mkdir -p "$ERRS"
ln "$1" "$ERRS"
else
PERCENTAGE=$((100*$TGT_SIZE/`stat -c %s "$1"`))
if [ "$PERCENTAGE" -lt 90 ]; then
echo "[$# left] $1 - ${PERCENTAGE}%"
TF="$TGT/${1##*/}"
if [[ ! $TF =~ \.jpe?g ]]; then
TF+=".jpg"
fi
mv -i "$TMPF" "$TF"
if [ "$COPY_EXIF" ]; then
exiftool -TagsFromFile "$1" -all:all -ThumbnailImage= -overwrite_original "$TF"
fi
touch -r "$1" "$TF"
else
echo "[$# left] $1 - ${PERCENTAGE}%, not successfull - hard-linking original"
ln -f "$1" "$TGT/$1"
fi
fi
fi
rm -f "$TMPF"
} &
while true; do
joblist=(`jobs -p`)
if [ ${#joblist[*]} -ge "$CPU_NUMBER" ]; then
wait -n
else
break
fi
done
shift
done
wait
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment