Skip to content

Instantly share code, notes, and snippets.

@JimBlaney
Created June 10, 2020 19:56
Show Gist options
  • Save JimBlaney/354c5627583f459a79f76863072e1783 to your computer and use it in GitHub Desktop.
Save JimBlaney/354c5627583f459a79f76863072e1783 to your computer and use it in GitHub Desktop.
#!/bin/bash
# depends on imagemagick and gifsicle
FONT_PATH=./fonts/Lato-Bold.ttf
contains () {
local e
for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done
return 1
}
usage () {
if [ "$1" != "" ]; then
echo -e "Error: $1\n" >&2
fi
echo "usage: $0 [options] <message>"
echo
echo "Options:"
echo
echo " -h Show this help message"
echo
echo " -o <output.gif> Path to output gif. Default: yolo.gif"
echo
echo " -c <color> Choose color set, valid options are:"
echo " red, orange, yellow, green, blue, purple,"
echo " pink, black, white. Default: blue"
echo
echo " -w Force white text color"
exit 1
}
VALID_COLORS=("red" "orange" "yellow" "green" "blue" "purple" "pink" "black" "white")
COLOR="white"
OUTPUT="output.gif"
FORCE_WHITE_TEXT=0
while getopts ":c:o:hw" opt; do
case $opt in
h)
usage
;;
w)
FORCE_WHITE_TEXT=1
;;
c)
if contains "$OPTARG" "${VALID_COLORS[@]}"; then
COLOR="$OPTARG"
else
usage "Invalid color: $OPTARG"
fi
;;
o)
OUTPUT="$OPTARG"
;;
\?)
usage "Invalid option: -$OPTARG"
;;
:)
usage "Option -$OPTARG requires an argument."
exit 1
;;
esac
done
shift $(($OPTIND - 1))
MESSAGE="$*"
if [ "$MESSAGE" == "" ]; then
usage "A message is required."
fi
case $COLOR in
red)
BACKGROUND="#ef4e65"
FILL="#8c2738"
;;
orange)
BACKGROUND="#f47820"
FILL="#8e4402"
;;
yellow)
BACKGROUND="#f0ce15"
FILL="#947c00"
;;
green)
BACKGROUND="#51bb7b"
FILL="#267048"
;;
blue)
BACKGROUND="#50c6db"
FILL="#01516e"
;;
purple)
BACKGROUND="#8351a0"
FILL="#4e2760"
;;
pink)
BACKGROUND="#e0368c"
FILL="#851252"
;;
black)
BACKGROUND="#5d5e5e"
FILL="#262727"
;;
white)
BACKGROUND="#ffffff"
FILL="#000000"
;;
esac
if [ "$FORCE_WHITE_TEXT" == 1 ]; then
FILL="#ffffff"
fi
# Make a "unique" prefix for this run
PREFIX="$(head -c 32 /dev/urandom | shasum | cut -b 1-10)"
# Generate image from text input
convert -background "$BACKGROUND" -fill "$FILL" -font "$FONT_PATH" -density 200 -pointsize 100 "label:${MESSAGE}" "/tmp/${PREFIX}_label.png"
# Resize to 128px high
convert -resize x128 "/tmp/${PREFIX}_label.png" "/tmp/${PREFIX}_sized.png"
# Add white space to front and back for empty frames
WIDTH="$(identify -format "%[fx:w]" "/tmp/${PREFIX}_sized.png")"
CANVAS_SIZE=$(($WIDTH + 276)) # 128 PX in front, 148 in back
convert -size ${CANVAS_SIZE}x128 "xc:$BACKGROUND" "/tmp/${PREFIX}_canvas.png"
convert "/tmp/${PREFIX}_canvas.png" "/tmp/${PREFIX}_sized.png" -geometry +128+0 -composite "/tmp/${PREFIX}_padded.png"
# Generate individual frames
OFFSET=0
I=0
LIMIT=$(($CANVAS_SIZE - 128))
while [ $OFFSET -lt $LIMIT ]; do
convert "/tmp/${PREFIX}_padded.png" -crop "128x128+${OFFSET}+0!" "$(printf "/tmp/${PREFIX}_frame_%05d.png" $I)"
I=$(($I + 1))
OFFSET=$(($OFFSET + 10))
done
ls -b /tmp/${PREFIX}_frame_*.png | xargs -I% convert -resize 48x48 % %
# Compile to gif
convert -delay 6 -loop 0 "/tmp/${PREFIX}_frame_*.png" "$OUTPUT"
# Smush it
gifsicle -bO "$OUTPUT"
# Clean up!
rm /tmp/${PREFIX}_*.png
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment