I thought it would be neat to include the date and weather on the images I use for my journal entry covers here on the blog.

It turned out to be neat, but not fun. I spent nearly 3 hours on all sorts of failed approaches. I figured it might be useful to write down where I ended up.

I leveraged two of my existing bash scripts that deal with the weather, and wrote a new one that uses ImageMagick to put things together.

Basically, I pass an image name to the script and it overlays the date at the bottom left and the weather at the bottom right. Like so…

~/bin/annotate-image.sh MyImage.jpg

Here is the result:

The results are still janky, but they work.

The results are still janky, but they work.

#!/bin/bash

# Check if an image name is provided
if [ "$#" -ne 1 ]; then
    echo "Usage: $0 <image_file>"
    exit 1
fi

IMAGE_FILE="$1"
OUTPUT_FILE="cover_$(basename "$IMAGE_FILE")"
WEATHER_URL="wttr.in/Grand+Rapids_0tqp0.png"
WEATHER_ICON=$(~/bin/getwcond)
WEATHER_ICON="/Users/jbaty/Sync/graphics/weather/64x64/day/$WEATHER_ICON"
CONDITIONS=$(~/bin/getweather | cut -f2 -d"|")


# Get current date in format "Friday, March 28, 2025"
CURRENT_DATE=$(date "+%A, %B %d, %Y")

# Add the weather info to the bottom right and the date to the bottom left
/opt/homebrew/bin/magick \
    "$IMAGE_FILE" \
    -fill white \
    -undercolor '#6F737880' \
    -font "Helvetica" \
    -pointsize 40 \
    -gravity SouthWest \
    -annotate +20+20 "$CURRENT_DATE" \
    -gravity SouthEast \
    -pointsize 30 \
    -annotate +20+20 "$CONDITIONS" \
    "$OUTPUT_FILE"

# Now overlay the weather from wttr onto the output from the previous command
/opt/homebrew/bin/magick composite \
    -gravity SouthEast \
    -geometry +20+60 \
    "$WEATHER_ICON" \
    "$OUTPUT_FILE" \
    "$OUTPUT_FILE"

echo "Weather added to image: $OUTPUT_FILE"

That script uses two other scripts that I wrote years ago for grabbing weather conditions getweather

#!/bin/sh
# Grab and parse weather info using WeatherAPI.com

jq=/opt/homebrew/bin/jq
weatherfile=`mktemp`
curl -s "https://api.weatherapi.com/v1/forecast.json?key=MYAPIKEY&q=MYZIP&days=1&aqi=no&alerts=no" > $weatherfile

now=`${jq} -r .current.condition.text ${weatherfile}`
temp=`${jq} -r .current.temp_f ${weatherfile}`
condition=`${jq} -r .forecast.forecastday[0].day.condition.text ${weatherfile}`
high=`${jq} -r .forecast.forecastday[0].day.maxtemp_f ${weatherfile}`
low=`${jq} -r .forecast.forecastday[0].day.mintemp_f ${weatherfile}`

echo "${now} ${temp} | Low ${low}, High ${high}"

Returns something like “Light rain 50.4 | Low 27.9, High 69.1”. I use cut to grab just the high/low temperature part.

Then there’s getwcond which is mostly a copy/paste job from the previous script. It returns the name of an image file for the current conditions (e.g. 234.png). I use this as the icon to overlay onto the image.

#!/bin/sh
# Jack Baty, 2023 (https://baty.net)
# Grab and parse weather info using WeatherAPI.com

jq=/opt/homebrew/bin/jq
weatherfile=`mktemp`
conditionfile=/Users/jbaty/Sync/graphics/weather/conditions.json
curl -s "https://api.weatherapi.com/v1/forecast.json?key=MYAPIKEY&q=MYZIP&days=1&aqi=no&alerts=no" > $weatherfile

code=`${jq} -r .forecast.forecastday[0].day.condition.code ${weatherfile}`
iconcond=`${jq} -r .current.condition.icon ${weatherfile}`
icon=$(${jq} '.[] | select(.code=='${code}').icon' ${conditionfile})

iconfile=$(basename $iconcond)
echo $iconfile

This all took me way too long. I could’ve pulled out the LLM crutch, but I really wanted to figure it out on my own. Next time I should just take the extra 2 minutes and use Photoshop instead :).