Skip to content

Instantly share code, notes, and snippets.

@NandoSangenetto
Last active August 24, 2022 08:22
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save NandoSangenetto/a889c7a192df2c0c9baf21a867ef351d to your computer and use it in GitHub Desktop.
Save NandoSangenetto/a889c7a192df2c0c9baf21a867ef351d to your computer and use it in GitHub Desktop.
Compress and convert images
# Convert images from folder
## Installation
You need to download libwebp and put in the shell script folder.
You must have installed the jpegoptim, giflossy (gifsicle), pngquant and imagemagick library.
## Usage
Convert folder and put results in the results folder
./convert.sh -p /path/to/folder
To overwrite the results folder, use this command
./convert.sh -p /path/to/folder -d /path/to/results
To change the default values of qualities:
./convert.sh -p /path/to/folder -q 70 -q 90 -q 100
Options:
-p images path (current path by default)
-d destination path (results folder by default)
-g enable gif conversion/optimization (optional, disabled by default)
-t name the temporary folder (.temp-folder by default)
-q use this parameter to change the quality of optimization/conversion (30, 50, 60, 70, 80, 100 by default)
Next steps:
* Identify the type of an image and fix the extension
* Use the type of an image as rule to the conditions, not the extension
#!/bin/bash
# Defining time to calculate execution
start_time=`date +%s`
# Enabling extglob option to filter file extensions
shopt -s extglob
# Exit if a command exits with a non-zero status
set -e
# Gif conversion/optimization disabled by default
gif_enabled=0
# Path to get images by default
image_path=.
# Temporary folder name, dot to hide the folder
temp_folder=.temp-folder
# Quality list to convert the images
qualities=()
destination_folder=""
# Get flag options
while getopts ":q:p:d:t:g" opt; do
case $opt in
# Set the qualities of files
q) qualities+=("$OPTARG") ;;
# Set the folder to scan
p) image_path="${OPTARG%/}" ;;
# Set the destination of the converted images
d) destination_folder="${OPTARG%/}" ;;
# Turn GIF conversion on
t) temp_folder="${OPTARG///}" ;;
# Turn GIF conversion on
g) gif_enabled=1 ;;
# Stop execution when an invalid option is called
\?) echo "Invalid option: -$OPTARG" >&2; exit 1; ;;
# Stop execution when an empty option is called
:) echo "Option -$OPTARG requires an argument." >&2; exit 1; ;;
esac
done
# Defining default values to the qualities
if [ -z "$qualities" ]; then
qualities=( 30 50 60 70 80 90 )
fi;
# If image_path is empty, lets ask the path
if [ -z "$image_path" ]; then
echo "Warning: Path parameter is missing, you must specify the folder to convert the images"
exit 1
fi;
# Defining the destination folder default value
if [ -z "$destination_folder" ]; then
destination_folder="${image_path}/results"
fi;
# Create the destination folder inside the path
mkdir -p ${destination_folder}
# Create a hidden temporary folder
mkdir -p ${image_path}/${temp_folder}
# If gif conversion/optimization is enabled, let's add them
if [ "$gif_enabled" -eq 1 ]; then
FILES=${image_path}/*.@(jpg|jpeg|png|gif)
else
FILES=${image_path}/*.@(jpg|jpeg|png)
fi;
# Check the number of files
number_of_files="$(find $FILES 2>/dev/null | wc -l)"
# If there's no files, exit the script
if [ ${number_of_files} -eq 0 ]; then
echo "There's no image in this folder"
exit 1;
fi;
# Loop to look every image with the extensions below
for f in ${FILES}; do
echo "File $f:";
# Defining the basename
base_name=$(basename "$f")
# Getting the name of the file without extension
name=${base_name%.*}
# Getting the file extension
extension=${base_name##*.}
# For every quality, lets convert images
for i in "${qualities[@]}"; do
# Optimize the JPG and JPEG
if [ "$extension" = "jpg" ] || [ "$extension" = "jpeg" ]; then
echo -e "\tOptimizing JPG/JPEG to $i quality"
# Define a name to a temporary file
temp_jpg_filename=${image_path}/${temp_folder}/${name}-q${i}.${extension}
# Copy the original file and create it with the temporary name
cp ${image_path}/${name}.${extension} ${temp_jpg_filename}
# Optimize the image and put in the destination folder
jpegoptim -o -q -m $i -d ${destination_folder} ${temp_jpg_filename}
# Remove the temporary file
rm ${temp_jpg_filename}
fi;
# Optimize static PNG files
if [ "$extension" = "png" ]; then
echo -e "\tOptimizing PNG with $i quality"
pngquant --speed 1 --quality ${i}-${i} -f -o ${destination_folder}/${name}-q${i}.png ${image_path}/${name}.${extension}
# Checking if there's transparency to the image
opaque=`convert ${image_path}/${name}.${extension} -format "%[opaque]" info:`
if [ "$opaque" = true ]; then
echo -e "\tConverting PNG to JPG, because there's no transparency"
# Convert the PNG to JPG
convert ${image_path}/${name}.${extension} ${destination_folder}/${name}-q${i}_from_png.jpg
echo -e "\tOptimizing JPG converted from PNG"
# Define a name to a temporary file
temp_jpg_filename=${image_path}/${temp_folder}/${name}-q${i}_from_png_optimized.jpg
# Copy the original file and create it with the temporary name
cp ${destination_folder}/${name}-q${i}_from_png.jpg ${temp_jpg_filename}
# Optimizing the JPG
jpegoptim -o -q -m $i -d ${destination_folder} ${temp_jpg_filename}
# Remove the temporary file
rm ${temp_jpg_filename}
fi;
fi;
# Convert static images to WEBP
if [ "$extension" = "jpg" ] || [ "$extension" = "jpeg" ] || [ "$extension" = "png" ]; then
echo -e "\tConverting to WEBP with $i quality"
./libwebp/bin/cwebp -quiet -m 6 -q $i ${image_path}/${name}.${extension} -o ${destination_folder}/${name}-q${i}.webp
fi;
# Convert gif/animated gif to WEBP
if [ "$extension" = "gif" ]; then
echo -e "\tConverting to WEBP with $i quality"
./libwebp/bin/gif2webp -quiet -lossy -q $i -m 6 ${image_path}/${name}.${extension} -o ${destination_folder}/${name}-q${i}.webp
fi;
done;
# Optimize GIF images/animations
if [ "$extension" = "gif" ]; then
echo -e "\tOptimizing GIF with lossy compression and 64 colors"
gifsicle -O3 --colors=64 --lossy=100 ${image_path}/${name}.${extension} -o ${destination_folder}/${name}-q64.gif
echo -e "\tOptimizing GIF with lossy compression and 125 colors"
gifsicle -O3 --colors=128 --lossy=100 ${image_path}/${name}.${extension} -o ${destination_folder}/${name}-q128.gif
echo -e "\tOptimizing GIF with lossy compression and 256 colors"
gifsicle -O3 --colors=256 --lossy=100 ${image_path}/${name}.${extension} -o ${destination_folder}/${name}-q256.gif
fi;
echo ""
done;
# Remove the hidden temporary folder
rm -rf ${image_path}/${temp_folder}
# Defining the end time for the execution calculation
end_time=`date +%s`
echo "Script finished in $((end_time-start_time)) seconds"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment