Created
April 2, 2017 12:55
-
-
Save tuttle/6ded6256c9e746083df51e267db43f42 to your computer and use it in GitHub Desktop.
This file contains 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 | |
# 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 <[email protected]>, 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