env-ansible/files/scripts/compress-images.sh

171 lines
4.6 KiB
Bash
Raw Normal View History

#!/bin/bash
# 2023-08-31 Hyperling
# Lower resolution of images for uploading to websites or keeping in storage.
# Also see: compress-video.sh
## Setup ##
DIR="$(dirname -- "${BASH_SOURCE[0]}")"
PROG="$(basename -- "${BASH_SOURCE[0]}")"
echo "Running $DIR/$PROG"
# Integers
typeset -i size status
size=2000
# Strings
tag="shrunk"
date_YYYYMMDD="`date "+%Y%m%d"`"
location="."
search="ls"
large_extension="DoNotUse-LargerThanOriginal"
large_created=".$PROG.large_created.true"
## Functions ##
function usage() {
# Hit the user with knowledge on how to use this program.
# Parameters:
# 1) The exit status to use.
status=$1
echo "Usage: $PROG [-s SIZE] [-l LOCATION] [-r] [-f] [-d] [-h] [-x]" >&2
cat <<- EOF
Compress JPG or PNG image(s). Can handle folders and work recursively.
Parameters:
-s SIZE : Integer for the maximum length of either image dimension.
-l LOCATION : The specific image or folder which needs images shrunk.
-r : Recursively shrink images based on the location passed.
-f : Force the image to be shrunk even if a file already exists for it.
-d : Delete the original image if the compressed image is smaller.
-h : Display this usage text.
-x : Enable BASH debugging.
EOF
exit $status
}
## Parameters ##
while getopts ":s:l:rfdhx" opt; do
case $opt in
s) in_size="$OPTARG" && size="$in_size" ;;
l) location="$OPTARG" ;;
r) recurse="Y" && search="find" ;;
f) force="Y" ;;
d) delete="Y" ;;
h) usage 0 ;;
x) set -x ;;
*) echo "ERROR: Option $OPTARG not recognized." >&2 && usage 1 ;;
esac
done
## Validations ##
if [[ -n "$in_size" && "$size" != "$in_size" ]]; then
echo "ERROR: Size value '$in_size' included non-integer characters." >&2
usage 1
fi
## Main ##
# If using ls, make sure full path is passed to the loop by adding '/*'.
if [[ -z "$recurse" && -d "$location" && "$location" != *'/*' ]]; then
if [[ "$location" != *'/' ]]; then
location="${location}/"
fi
location="${location}*"
fi
$search "$location" | sort | while read image; do
# Avoid processing directories no matter the name.
[ -d "$image" ] && continue
# Avoid processing files previously shrunk.
[[ "$image" == *"$tag"* ]] && continue
echo -e "\n$image"
# Only look through JPG and PNG for now.
typeset -l extension
extension="${image##*.}"
if [[ "$extension" != *"jpg"
&& "$extension" != *"jpeg"
&& "$extension" != *"png" ]]
then
echo " SKIP: Sorry, currently only JPG and PNG are supported."
continue
fi
new_image="${image//.$extension/}.$tag-$date_YYYYMMDD.$extension"
# Delete the existing shrunk image if we are forcing a new compression.
if [[ -n "$force" && -e "$new_image" ]]; then
echo -n " FORCE: "
rm -v "$new_image"
fi
# Skip if a compressed image was already created today.
if [[ -e "$new_image" ]]; then
echo " SKIP: Image has already been shrunk previously, moving on."
continue
fi
# This modifies the image to be $size at its longest end, not be a square.
convert "$image" -resize ${size}x${size} "$new_image"
# Check file sizes and if the new one is larger then flag it as large.
echo " Checking file sizes:"
ls -sh "$image" "$new_image" | sort -hr | while read line; do
echo " $line"
done
smaller_file=`
ls -sh "$image" "$new_image" | sort -h | awk '{print $2}' | head -n 1
`
if [[ "$smaller_file" == "$image" ]]; then
echo -n " WARNING: Conversion caused growth, original was likely lesser "
echo "quality. Adding a suffix to the file to signify that it may be bad."
echo -n " "
mv -v "$new_image" "$new_image.$large_extension"
touch "$large_created"
continue
fi
echo " SUCCESS: Conversion succeeded, file has been compressed."
if [[ -n "$delete" ]]; then
echo -n " DELETE: "
if [[ -d ~/TRASH ]]; then
mv -v "$image" ~/TRASH/
else
rm -v "$image"
fi
fi
done
# If large files do end up being created, allow the user to bulk delete them.
echo "FORTEST"
if [[ -e "$large_created" ]]; then
echo -e "\n*********************************************************"
echo -e "WARNING: The files below are larger than their originals!\n"
find "$location" -name "*"$large_extension
echo -e "*********************************************************"
echo -en "\nWould you like to delete them? (Y/n): "
typeset -u confirm_delete
read confirm_delete
if [[ -z "$confirm_delete" || "$confirm_delete" == "Y"* ]]; then
echo ""
find "$location" -name "*"$large_extension -exec rm -v {} \;
else
echo -e "\nKeeping files. Please use this if you change your mind:"
echo " find \"$location\" -name \"*\"$large_extension -exec rm -v {} \;"
fi
rm "$large_created"
fi
echo -e "\nDone!"
exit 0