img-optimize/optimize.sh

299 lines
10 KiB
Bash
Executable File

#!/usr/bin/env bash
#----------------------------------------------------------------------------
# img-optimize- Image optimization bash script
#----------------------------------------------------------------------------
# Website: https://virtubox.net
# GitHub: https://github.com/VirtuBox/img-optimize
# Author: VirtuBox
# License: M.I.T
# ----------------------------------------------------------------------------
# Version 2.0 - 2020-11-10
# ----------------------------------------------------------------------------
CSI='\033['
CEND="${CSI}0m"
CGREEN="${CSI}1;32m"
FIND_ARGS=""
PNG_ARGS=""
JPG_ARGS=""
WEBP_ARGS=""
IMG_PATH="$PWD"
_help() {
echo "Bash script to optimize your images and convert them in WebP "
echo "Usage: img-optimize [options] <images path>"
echo "If images path isn't defined, img-optimize will use the current directory "
echo " Options:"
echo " --jpg ..... optimize all jpg images"
echo " --png ..... optimize all png images"
echo " --webp ..... convert all images in webp"
echo " --avif ..... convert all images in avif"
echo " --std ..... optimize all png & jpg images"
echo " --next ..... convert all images in webp & avif"
echo " --all ..... optimize all images (png + jpg + webp + avif)"
echo " -i, --interactive ..... run img-optimize in interactive mode"
echo " -q, --quiet ..... run image optimization quietly"
echo " --path <images path> ..... define images path"
echo " Other options :"
echo " -h, --help, help ... displays this help information"
echo " --cmin [+|-]<n> ... File's status was last changed n minutes ago."
echo " act find cmin argument (+n : greater than n, -n : less than n, n : exactly n)"
echo "Examples:"
echo " optimize all jpg images in /var/www/images"
echo " img-optimize --jpg --path /var/www/images"
echo ""
return 0
}
##################################
# Parse script arguments
##################################
if [ "${#}" = "0" ]; then
_help
exit 1
else
while [ "$#" -gt 0 ]; do
case "$1" in
--jpg)
JPG_OPTIMIZATION="y"
;;
--png)
PNG_OPTIMIZATION="y"
;;
--std)
JPG_OPTIMIZATION="y"
PNG_OPTIMIZATION="y"
WEBP_OPTIMIZATION="n"
AVIF_OPTIMIZATION="n"
;;
--next)
AVIF_OPTIMIZATION="y"
WEBP_OPTIMIZATION="y"
;;
--webp)
WEBP_OPTIMIZATION="y"
;;
--avif)
AVIF_OPTIMIZATION="y"
;;
--all)
PNG_OPTIMIZATION="y"
JPG_OPTIMIZATION="y"
WEBP_OPTIMIZATION="y"
AVIF_OPTIMIZATION="y"
;;
-i | --interactive)
INTERACTIVE_MODE="1"
;;
-q | --quiet)
PNG_ARGS=" -quiet"
JPG_ARGS=" --quiet"
WEBP_ARGS=" -quiet"
;;
--cmin)
if [ -n "$2" ]; then
FIND_ARGS="$2"
shift
fi
;;
--path)
if [ -n "$2" ]; then
IMG_PATH="$2"
shift
fi
;;
-h | --help | help)
_help
exit 1
;;
*) ;;
esac
shift
done
fi
##################################
# Prevent multi execution on same directory
##################################
lock=$(echo -n "$IMG_PATH" | md5sum| cut -d" " -f1)
if [ -f "/tmp/$lock" ]; then
echo "$IMG_PATH yet in progress"
exit 1
else
touch "/tmp/$lock"
fi
##################################
# Welcome
##################################
echo ""
echo "Welcome to optimize.sh image optimization script."
echo ""
if [ "$INTERACTIVE_MODE" = "1" ]; then
if [ -z "$IMG_PATH" ]; then
echo "What is the path of images you want to optimize ?"
echo "Images path (eg. /var/www/images):"
read -r IMG_PATH
fi
if [ -z "$JPG_OPTIMIZATION" ]; then
echo ""
echo "Do you want to optimize all jpg images in $IMG_PATH ? (y/n)"
while [[ $JPG_OPTIMIZATION != "y" && $JPG_OPTIMIZATION != "n" ]]; do
echo "Select an option [y/n]: "
read -r JPG_OPTIMIZATION
done
fi
if [ -z "$PNG_OPTIMIZATION" ]; then
echo ""
echo "Do you want to optimize all png images in $IMG_PATH (it may take a while) ? (y/n)"
while [[ $PNG_OPTIMIZATION != "y" && $PNG_OPTIMIZATION != "n" ]]; do
echo "Select an option [y/n]: "
read -r PNG_OPTIMIZATION
done
fi
if [ -z "$WEBP_OPTIMIZATION" ]; then
echo ""
echo "Do you want to convert all jpg & png images to WebP in $IMG_PATH ? (y/n)"
while [[ $WEBP_OPTIMIZATION != "y" && $WEBP_OPTIMIZATION != "n" ]]; do
echo "Select an option [y/n]: "
read -r WEBP_OPTIMIZATION
done
echo ""
echo ""
fi
if [ -z "$AVIF_OPTIMIZATION" ]; then
echo ""
echo "Do you want to convert all jpg & png images to WebP in $IMG_PATH ? (y/n)"
while [[ $AVIF_OPTIMIZATION != "y" && $AVIF_OPTIMIZATION != "n" ]]; do
echo "Select an option [y/n]: "
read -r AVIF_OPTIMIZATION
done
echo ""
echo ""
fi
fi
##################################
# image optimization
##################################
# optimize jpg
if [ "$JPG_OPTIMIZATION" = "y" ]; then
[ -z "$(command -v jpegoptim)" ] && {
echo "Error: jpegoptim isn't installed"
# Free ressource
rm "/tmp/$lock"
exit 1
}
echo -ne ' jpg optimization [..]\r'
cd "$IMG_PATH" || exit 1
if [ -n "$FIND_ARGS" ]; then
find . -type f \( -iname "*.jpg" -o -iname "*.jpeg" \) -cmin "$FIND_ARGS" -print0 | xargs -r -0 jpegoptim "$JPG_ARGS" -p -s --all-progressive -m82
else
find . -type f \( -iname "*.jpg" -o -iname "*.jpeg" \) -print0 | xargs -r -0 jpegoptim "$JPG_ARGS" -p -s -m82 --all-progressive
fi
echo -ne " jpg optimization [${CGREEN}OK${CEND}]\\r"
echo -ne '\n'
fi
if [ "$PNG_OPTIMIZATION" = "y" ]; then
[ -z "$(command -v optipng)" ] && {
echo "Error: optipng isn't installed"
# Free ressource
rm "/tmp/$lock"
exit 1
}
# optimize png
echo -ne ' png optimization [..]\r'
cd "$IMG_PATH" || (rm "/tmp/$lock" && exit 1)
if [ -n "$FIND_ARGS" ]; then
find . -type f -iname '*.png' -cmin "$FIND_ARGS" -print0 | xargs -r -0 optipng "$PNG_ARGS" -o5 -strip all
else
find . -type f -iname '*.png' -print0 | xargs -r -0 optipng "$PNG_ARGS" -o5 -strip all
fi
echo -ne " png optimization [${CGREEN}OK${CEND}]\\r"
echo -ne '\n'
fi
if [ "$WEBP_OPTIMIZATION" = "y" ]; then
[ -z "$(command -v cwebp)" ] && {
echo "Error: cwebp isn't installed"
# Free ressource
rm "/tmp/$lock"
exit 1
}
# convert png to webp
echo -ne ' png to webp conversion [..]\r'
cd "$IMG_PATH" || (rm "/tmp/$lock" && exit 1)
if [ -n "$FIND_ARGS" ]; then
find . -type f -iname "*.png" -cmin "$FIND_ARGS" -print0 | xargs -0 -r -I {} \
bash -c "[ ! -f '{}.webp' ] && { cwebp -z 9 -mt $WEBP_ARGS '{}' -o '{}.webp'; }"
else
find . -type f -iname "*.png" -print0 | xargs -0 -r -I {} \
bash -c "[ ! -f '{}.webp' ] && { cwebp -z 9 -mt $WEBP_ARGS '{}' -o '{}.webp'; }"
fi
echo -ne " png to webp conversion [${CGREEN}OK${CEND}]\\r"
echo -ne '\n'
# convert jpg to webp
echo -ne ' jpg to webp conversion [..]\r'
cd "$IMG_PATH" || (rm "/tmp/$lock" && exit 1)
if [ -n "$FIND_ARGS" ]; then
find . -type f \( -iname "*.jpg" -o -iname "*.jpeg" \) -cmin "$FIND_ARGS" -print0 | xargs -0 -r -I {} \
bash -c "[ ! -f '{}.webp' ] && { cwebp $WEBP_ARGS -q 82 -mt '{}' -o '{}.webp || rm -f '{}.webp''; }"
else
find . -type f \( -iname "*.jpg" -o -iname "*.jpeg" \) -print0 | xargs -0 -r -I {} \
bash -c "[ ! -f '{}.webp' ] && { cwebp $WEBP_ARGS -q 82 -mt '{}' -o '{}.webp' || rm -f '{}.webp'; }"
fi
echo -ne " jpg to webp conversion [${CGREEN}OK${CEND}]\\r"
echo -ne '\n'
fi
if [ "$AVIF_OPTIMIZATION" = "y" ]; then
[ -z "$(command -v avif)" ] && {
echo "Error: avif isn't installed"
# Free ressource
rm "/tmp/$lock"
exit 1
}
# convert png to avif
echo -ne ' png to avif conversion [..]\r'
cd "$IMG_PATH" || (rm "/tmp/$lock" && exit 1)
if [ -n "$FIND_ARGS" ]; then
find . -type f -iname "*.png" -cmin "$FIND_ARGS" -print0 | xargs -0 -r -I {} \
bash -c "[ ! -f '{}.avif' ] && { avif -e '{}' -o '{}.avif' || rm -f '{}.avif'; }"
else
find . -type f -iname "*.png" -print0 | xargs -0 -r -I {} \
bash -c "[ ! -f '{}.avif' ] && { avif -e '{}' -o '{}.avif' || rm -f '{}.avif'; }"
fi
echo -ne " png to avif conversion [${CGREEN}OK${CEND}]\\r"
echo -ne '\n'
# convert jpg to avif
echo -ne ' jpg to avif conversion [..]\r'
cd "$IMG_PATH" || (rm "/tmp/$lock" && exit 1)
if [ -n "$FIND_ARGS" ]; then
find . -type f \( -iname "*.jpg" -o -iname "*.jpeg" \) -cmin "$FIND_ARGS" -print0 | xargs -0 -r -I {} \
bash -c "[ ! -f '{}.avif' ] && { avif -e '{}' -o '{}.avif' || rm -f '{}.avif'; } "
else
find . -type f \( -iname "*.jpg" -o -iname "*.jpeg" \) -print0 | xargs -0 -r -I {} \
bash -c "[ ! -f '{}.avif' ] && { avif -e '{}' -o '{}.avif' || rm -f '{}.avif'; }"
fi
echo -ne " jpg to avif conversion [${CGREEN}OK${CEND}]\\r"
echo -ne '\n'
fi
# We're done !
echo ""
echo -e " ${CGREEN}Image optimization performed successfully !${CEND}"
echo ""
# Free ressource
rm "/tmp/$lock"