Last active
August 6, 2024 10:17
-
-
Save robbaier/37729a68a36e81936000fdaade1fb8b1 to your computer and use it in GitHub Desktop.
Script to optimize GIFs. Uses Gifsicle to drop frames, increase delay, reduce color depth and optimize
This file contains hidden or 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/sh | |
# Script: gif-optimize.sh | |
# Author: Rob Baier | |
# Description: Script used to optimize animated GIF files. | |
# Dependencies: Gifsicle (https://github.com/kohler/gifsicle) | |
# Environment: Tested on MacOS 10.12. Other *nix environments may require some tweaking. | |
# Usage: ./gif-optimize.sh input-filename.gif | |
# Helper function to convert bytes into a human-readable format | |
bytesReadable() { | |
b=${1:-0}; d=''; s=0; S=(Bytes {K,M,G,T,E,P,Y,Z}iB) | |
while ((b > 1024)); do | |
d="$(printf ".%02d" $((b % 1024 * 100 / 1024)))" | |
b=$((b / 1024)) | |
let s++ | |
done | |
echo "$b$d ${S[$s]}" | |
} | |
# The output filename will have "-min.gif" appended automatically | |
INPUT_FILE=$1 | |
INPUT_FILEINFO=`gifsicle -I $1` | |
INPUT_FILESIZE=`cat $1 | wc -c` | |
INPUT_FILESIZE_READABLE=`bytesReadable $INPUT_FILESIZE` | |
FILENAME="${INPUT_FILE%.*}" | |
OUTPUT_FILE="$FILENAME-min.gif" | |
# The delay factor determines how many frames will be removed and what the new frame delay will be | |
# in order to maintain the same animation speed as the original file. A delay factor of 2 will remove | |
# every other frame and double the frame delay in the new file. Increasing this number will drop more | |
# frames and reduce the overall filesize, but will result in a more choppy animation. | |
DELAY_FACTOR=2 | |
# Set the number of colors in the output file | |
COLOR_DEPTH=24 | |
# Get the number of frames from the original file | |
NUM_FRAMES=`echo "$INPUT_FILEINFO" | grep -E "[0-9]+ images" --only-matching | grep -E "[0-9]+" --only-matching` | |
# Get the frame delay from the original file | |
DELAY=`echo "$INPUT_FILEINFO" | grep -E "delay [0-9].+" --only-matching | grep -E "[0-9].+" --only-matching | tail -1 | rev | cut -c 2- | rev` | |
# Get the color depth from the original file | |
INPUT_COLORS=`echo "$INPUT_FILEINFO" | grep "color" | grep -oE "[0-9]." --only-matching` | |
# Calculate new delay based on original delay and the new delay factor | |
NEW_DELAY=$(expr $DELAY*100*$DELAY_FACTOR | bc) | |
NEW_DELAY=${NEW_DELAY%%.*} | |
gifsicle -U $INPUT_FILE --delay $NEW_DELAY `seq -f "#%g" 0 $DELAY_FACTOR $NUM_FRAMES` -O3 --colors $COLOR_DEPTH -o $OUTPUT_FILE | |
OUTPUT_FILEINFO=`gifsicle $OUTPUT_FILE -I` | |
OUTPUT_FRAMES=`echo "$OUTPUT_FILEINFO" | grep -E "[0-9]+ images" --only-matching | grep -E "[0-9]+" --only-matching` | |
OUTPUT_COLORS=`echo "$OUTPUT_FILEINFO" | grep "color" | grep -oE "[0-9]." --only-matching` | |
OUTPUT_FILESIZE=`cat $OUTPUT_FILE | wc -c` | |
OUTPUT_FILESIZE_READABLE=`bytesReadable $OUTPUT_FILESIZE` | |
echo " Original file: $INPUT_FILESIZE_READABLE ($NUM_FRAMES frames, $INPUT_COLORS colors)" | |
echo "Optimized file: $OUTPUT_FILESIZE_READABLE ($OUTPUT_FRAMES frames, $OUTPUT_COLORS colors)" | |
if [ $INPUT_FILESIZE > $OUTPUT_FILESIZE ]; then | |
FILESIZE_DIFF=$((INPUT_FILESIZE-OUTPUT_FILESIZE)) | |
FILESIZE_DIFF_READABLE=`bytesReadable $FILESIZE_DIFF` | |
echo " Saved: $FILESIZE_DIFF_READABLE" | |
fi |
Worked great! Huge timesaver! Thanks for writing this. I downsized a bunch of problematic gifs for slack that wouldn't upload. Several of them didn't take the downsizing well and started playing too slow to use. I may just increase the replay speed for these but 90% of them came out great. 🥂
Thanks!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks. Works like a charm. Could you recommend an if-clause, where I can set a target size of the output file? Like the compressed gif needs to be smaller than 100kb, start with a delay factor of 2 and increase the factor, if the file size is not below the 100kb. Thanks a lot!