I clicked 'click here to enlarge' but I'm still the same size!

Image Magick Banner Generator - part 4

Date/Time Permalink: 03/22/08 11:30:04 am
Category: Graphics Tutorials

OK, the day we've been waiting for: the thing that's going to actually make text banners out of all these parts!

Here it be, saved as "random_banner.sh":

#!/bin/bash

if [ "$1" ]; then
  TEXT="$1"
else
  echo "USAGE random_banner.sh TEXT"
  exit 1
fi

# A basic text banner
  echo "$TEXT" > temp_text
  ls /usr/X11R6/lib/X11/fonts/TTF/*.ttf > temp_font_list
  FONT=$(./random_line.sh temp_font_list)
  rm temp_font_list
  FGCOLOR=$(./random_line.sh /usr/X11R6/lib/X11/rgb.txt | cut -f 3- | sed 's/[ \t]*//g')

  CONVERTSTRING=" -background none"
  CONVERTSTRING="$CONVERTSTRING"" -fill ""$FGCOLOR"
  if [ "$(($RANDOM % 2))" = 1 ]; then
    STROKECOLOR=$(./random_line.sh /usr/X11R6/lib/X11/rgb.txt | cut -f 3- | sed 's/[ \t]*//g')
    CONVERTSTRING="$CONVERTSTRING"" -strokewidth 1"
    CONVERTSTRING="$CONVERTSTRING"" -stroke ""$STROKECOLOR"
  fi

  CONVERTSTRING="$CONVERTSTRING"" -font ""$FONT"
  CONVERTSTRING="$CONVERTSTRING"" -pointsize ""$(($RANDOM % 40 + 30))"
  CONVERTSTRING="$CONVERTSTRING"" label:@temp_text"
  CONVERTSTRING="$CONVERTSTRING"" -gravity center Banner.png"

#  echo $CONVERTSTRING
  convert $CONVERTSTRING
  rm temp_text

# Some special effects for the text?
# Like, say, a wave?
  if [ "$(($RANDOM % 8))" = 1 ]; then
    WAVESTRING="Banner.png -matte -background none -wave "
    WAVESTRING="$WAVESTRING""$(($RANDOM % 5 + 3))"x"$(($RANDOM % 200 + 200))"" Banner.png"
    convert $WAVESTRING
  fi
# Perhaps some shade?
  if [ "$(($RANDOM % 2))" = 1 ]; then
# Maybe with a blur?
    if [ "$(($RANDOM % 2))" = 1 ]; then
      BLURSTRING="Banner.png -blur 0x""$(($RANDOM % 4 + 3))"" Banner.png"
      convert $BLURSTRING
    fi
    SHADESTRING="Banner.png -shade ""$(($RANDOM % 180 + 0))""x""$(($RANDOM % 40 + 5))"" Banner.png"
    convert $SHADESTRING
# Since we shaded it, it's gray now, so tint it back.
    TINTSTRING="Banner.png -fill ""$FGCOLOR"" -tint ""$(($RANDOM % 80 + 60)) Banner.png"
    convert $TINTSTRING
  fi


# Get the size of the text banner, then pad it a little
  IMGSIZE=$(identify Banner.png | awk '{print $3}')
  IMGX=$(echo $IMGSIZE | awk -Fx '{print $1}')
  IMGY=$(echo $IMGSIZE | awk -Fx '{print $2}')
  IMGX=$(($IMGX + $(($IMGX / 10))))
  IMGY=$(($IMGY + $(($IMGY / 30))))
  IMGSIZE=$IMGX"x"$IMGY

# Make a background to fit the banner
  case $(($RANDOM % 4 +1)) in
    1)
      ./generate_background_solid.sh $IMGSIZE
      ;;
    2)
      ./generate_background_gradient.sh $IMGSIZE
      ;;
    3)
      ./generate_background_pattern.sh $IMGSIZE
      ;;
    4)
      ./generate_background_noise.sh $IMGSIZE
      ;;
  esac

  composite -gravity center Banner.png background.png Banner.png
  rm background.png

# Chance of bevel or frame
  if [ "$(($RANDOM % 2))" = 1 ]; then
    ./bevel.sh Banner.png
  fi
  if [ "$(($RANDOM % 2))" = 1 ]; then
    ./frame.sh Banner.png
  fi

exit 0

It's a doozy! Here's a section-by-section breakdown:

  • All it needs to start is the text string, which you must quote. Example: ./random_banner.sh "your text here"
  • Next it uses the random line script to pick out a random font from your X11's font library. Because I have free fonts running out my ears, I get a lot of variety. If you don't have many fonts, you won't get much. You won't get anything but an error if /usr/X11R6/lib/X11/fonts/TTF/ is empty. Will this work with other kinds of fonts? I dunno yet.
  • Anyway, it pumps your text string using that font into a backless banner, sized automatically to suit the text.
  • Then it rolls the dice to see about applying special effects, being waves, blurring or shading.
  • Now it has the text banner saved, so it has to use the 'identify' command to find out how big the banner is, then size it a bit larger.
  • Then based on those specs, it picks one of the background-generating scripts we've been yammering about the past few days.
  • It generates the background and slaps the text on top of it with the 'composite' command, and rolls the dice one last time to see about applying a frame or bevel or both.

Ding! It's done! Now, some bugs and problems:

First, there's no control for making sure you can read it. It might pick pink text on a pink-to-purple gradient background. The best practice is to run it a few times, saving over the old banner, until you get a nice one.

Second, a big issue, is that the top and bottoms of fonts tend to get clipped. This only happens with improperly made fonts, which don't have good information on where the boundaries lie for individual letters. This is what happens when you download a lot of free fonts over the Internet. People just grab an old file, paste their letter shapes in over the old ones, save it and upload it. "Kerning" is not in their vocabulary. See a discussion of this here.

Last, you're going to get some banners that are just ghastly. Just try again. I've put as many controls as I can in here to reduce the "dud rate", but after all we're asking it to randomly create banners with as much creative freedom as possible. It's meant as an amusing toy and a way to show some of IM's more sophisticated capabilities, not a full-fledged enterprise software.

For instance, I just typed

./random_banner.sh "Image Magick rocks"

and got 'Banner.png'...

Image Magick rocks

...but who knows what you'll get next time?

IMBG.tar.gz

And at last, ▲ here's the promised tarball of all the scripts in one handy directory called "IMBG" (Image Magick Banner Generator), complete with GPL license! Yes, world, it is yours! Run away, little program, go free! However, it could stand to be more robust if anybody's going to take it seriously.

Also included in the tarball is a small script that generates 100 banners with two randomly picked words each and saves them in a subdirectory called "banner_gallery". We'll explore that little appendix to the project and the fascinating results next time.

Still another random sig

The whole Image Magick Banner Generator project:

part 1 - get a random line from a file, applying bevels and borders to an image.
part 2 - generate a solid or gradient background.
part 3 - generate a pattern or plasma noise background.
part 4 - generate the text itself, and use all of the previous scripts to make a banner.
part 5 - a final wrapper script, and some funny results.
Project Tarball with all scripts, GPL'ed

Useful Image Magick links:

Image Magick home page manual
Examples of ImageMagick Usage - a fantastic suite of tutorials!
Fred's Image Magick scripts

Follow me on Twitter for an update every time this blog gets a post.
Stumble it Reddit this share on Facebook

suddenly the moon