ImageMagick and GeekTool (or NerdTool)

[Tweet : ADN : nvALT]

This is going to be a relatively quick post, and it’s definitely aimed at people who can already find their way around the command line, and probably have a little experience with GeekTool and/or NerdTool as well.

I kind of stumbled on this concept while working on something unrelated. Basically, you pipe output from a shell command into ImageMagick’s convert command as a label, and then manipulate it to get an image you can display on your desktop. It allows for reflections, rotations, gradients and all kinds of fun things you could never do with a shell Geeklet alone. As an experiment, I just wanted a basic reflection, with a little bit of vertical text…

Here’s what I was aiming for:

Reflection Gradient Small

Here’s how I got it:

  1. Install ImageMagick. It’s easiest with Homebrew (brew install imagemagick), but you’ll figure out a way. Think you already have it? Check for the convert command. (Also make sure you have GhostScript, which should be installed by HomeBrew. Thanks to Rich G. for the catch.)
  2. Install the script below in ~/scripts/shadow.sh (you can put it anywhere, just be sure to modify the upcoming instructions appropriately).
  3. Make the script executable: chmod a+x ~/scripts/shadow.sh
  4. Set up a shell geeklet or nerdlet (GeekTool or NerdTool) to refresh every 60 seconds and run this command: ~/scripts/shadow.sh 2>&1. Alternatively, you can run this with cron. Make the Geeklet invisible by sizing it or setting transparency on it.
  5. Add an Image geek/nerdlet to display /Users/yourusername/reflected.png. Make it really big, left aligned and turn off scaling. Set the refresh time to 60 seconds. Since it’s not running a shell script, you could probably set it to 10 seconds and not raise CPU average load noticeably. Your choice.

Here’s the script:

#!/bin/bash

# ======= CONFIG ============================================
# set this to the location of ImageMagick's convert command
CONVERTER="/usr/local/bin/convert"
# set this to the location where your Image geeklet will look
OUTFILE="$HOME/reflected.jpg"
# ===========================================================

# don't mess with these
workdir=$TMPDIR
infile="$workdir/combo.png"

# create the pieces of the date (year, month, day) in $TMPDIR
date +'%Y' | $CONVERTER -background none -fill white -kerning -9 -font Helvetica -pointsize 120 -trim -bordercolor none -border 0x8 label:@- $workdir/year.png
date +'%A %I:%M%p' | $CONVERTER -background none -fill white -kerning 10 -font Helvetica -pointsize 70 -trim -bordercolor none -border 0x8 label:@- $workdir/day.png
date +'%B %d' | $CONVERTER -background none -fill white -kerning 0 -font Helvetica -pointsize 200 label:@- -trim $workdir/month.png
# stack the day on top of the month
$CONVERTER $workdir/day.png $workdir/month.png -background none -trim -append $workdir/daymonth.png
# rotate the result 90 degrees
$CONVERTER $workdir/daymonth.png -background none -trim -rotate 90 $workdir/daymonth90.png
# stack the year on top of the rotated day/month and rotate the result -90 degrees
$CONVERTER $workdir/year.png $workdir/daymonth90.png -gravity northeast -background none -append -rotate -90 $infile
# set the width and height variables
ww=`$CONVERTER $infile -format "%w" info:`
hh=`$CONVERTER $infile -format "%h" info:`
hhr=`$CONVERTER xc: -format "%[fx:$hh*40/50]" info:`
# clone the original image, flip it, composite a gradient and append it below the original
$CONVERTER $infile \
\( -size ${ww}x0 xc:none \) \
\( -clone 0 -flip +repage \) \
\( -clone 0 -alpha extract -flip +repage \
-size ${ww}x${hh} gradient: +level 0x50% \
-compose multiply -composite \) \
\( -clone 2 -clone 3 -alpha off -compose copy_opacity -composite \) \
-delete 2,3 -channel rgba -alpha on -background none -append $OUTFILE
exit 0

The script is adapted from one I found at imagemagick.org’s forum, and there’s a good breakdown of how it works at the bottom of the thread.

You should see something like the image above on your desktop now, if all went well. If not, first look for the output file (~/reflected.png) and see if it exists. If it does, check your image geeklet. If it doesn’t, try executing the script on the command line and see what happens (~/scripts/shadow.sh). Any error messages you get will help you start debugging.

There are a lot of fancy things you can do with ImageMagick, but this is what I had time to throw together. Play with the settings, and then find some decent documentation for ImageMagick and do something way cooler!