|
#!/bin/bash |
|
|
|
# Find our font before we do anything. |
|
FONT_PATH="$(find $HOME/Library/Fonts/ -name 'Heartwell 1.2.otf')" |
|
if [ "$FONT_PATH" == "" ]; then |
|
FONT_PATH="$(find /Library/Fonts/ -name 'Heartwell 1.2.otf')" |
|
fi |
|
|
|
if [ "$FONT_PATH" == "" ]; then |
|
usage "Could not find 'Heartwell 1.2.otf'. Is it installed?" |
|
fi |
|
|
|
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="blue" |
|
OUTPUT="yolo.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 |
|
|
|
# Compile to gif |
|
convert -delay 6 -loop 0 "/tmp/${PREFIX}_frame_*.png" "$OUTPUT" |
|
|
|
# Smush it |
|
gifsicle -bO "$OUTPUT" |
|
|
|
# Clean up! |
|
rm /tmp/${PREFIX}_*.png |
fyi if you change script to use black BACKGROUND of #000000 this will cause all color to be lost. Quick workaround BACKGROUND="#010000" so some color is in there. A better solution is to instead add '-colorspace sRGB' flag to the two lines that handle /tmp/${PREFIX}_canvas.png.
Why this is happening. When /tmp/${PREFIX}_canvas.png is created convert tries to be smart and makes that image grayscale if background is black. As a result when /tmp/${PREFIX}_canvas.png is combined to the rest of the images all images will become grayscale. Further when ffmpeg creates gif and the pallete filter is applied, the filter will create further issues such as turning text into only white outline.