Skip to content

Instantly share code, notes, and snippets.

@jmhobbs
Last active March 24, 2023 15:19
Show Gist options
  • Save jmhobbs/b6ba8f5d1f816506e5b671c1bd89c723 to your computer and use it in GitHub Desktop.
Save jmhobbs/b6ba8f5d1f816506e5b671c1bd89c723 to your computer and use it in GitHub Desktop.
Create scrolling text gifs for Slack

Makes little scrolly text jiffs in Flywheel colors.

Prerequisites

  • imagemagick brew install imagemagick
  • gifsicle brew install gifsicle
  • Heartwell 1.2.otf font installed
  • u r on a mac

Usage

usage: yolo.sh [options] <message>

Options:

  -h                Show this help message

  -o <output.gif>   Path to output gif. Default: yolo.gif

  -c <color>        Choose color set, valid options are:
                    red, orange, yellow, green, blue, purple,
                    pink, black, white.  Default: blue

 -w                 Force white text color

Examples

$ yolo.sh -c orange -o gtfo.gif GTFO

GTFO

$ yolo.sh -c purple -w YOLO

YOLO

#!/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
@benstevinson
Copy link

🥇

@splitinfinities
Copy link

they're good script brant

@BoD
Copy link

BoD commented Jun 12, 2019

FYI for some reason with the latest version of Imagemagick, for this to work correctly, you need to add +repage to the last convert command.

@cyphunk
Copy link

cyphunk commented Dec 13, 2022

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment