Using ImageMagick to Save the Character Screen for Diablo II
Sometimes I speedrun Diablo II and want to stream my runs and show my audience my current stats, such as my level and resistances. I could just run around all the time with my character screen open, but then I would be stuck with a half a screen all the time. If only there was a tool that would extract this information from memory and show it on stream. Oh wait — there is — and it’s called DiabloInterface and it’s awesome!
However, I use Linux and that kind of memory peeking doesn’t seem to be working in wine. Understandably, it’s a issue marked as wontfix. In a perfect world I would modify that code to work with /proc/pid/mem — but this world ain’t perfect and I’ve got Diablos to slay.
So, we need a simple solution. ImageMagick to the rescue! It provides the import command for grabbing screenshots, convert to crop out a portion of the image and compare command to see if the character screen is visible.
First take a screenshot with:
import -window 'Diablo II' /tmp/d2screen.bmp
The screenshot is saved as a BMP file to avoid wasting time compressing or decompressing to PNG.
Now let’s extract a portion of the image we will use to check if the character screen is open:
convert /tmp/d2screen.bmp -crop 67x20+89+143 /tmp/is_char_screen.bmp
Now we can compare the two images and see if they are the same:
compare -metric RMSE strength_template.bmp /tmp/is_char_screen.bmp /dev/null 2> /dev/null
The compare command will use the exit status of 0
when they are similar images. We can use this to save the screenshot to a known location which OBS will automatically reload and it can be displayed on stream
The end result is this bash script:
#!/usr/bin/env bashwhile true; do
# Grab the current Diablo II screen
import -window 'Diablo II' /tmp/d2screen.bmp# Extract the area where "Strength" is shown
convert /tmp/d2screen.bmp -crop 67x20+89+143 /tmp/is_char_screen.bmp# Check if it matches a template image
compare -metric RMSE strength_template.bmp /tmp/is_char_screen.bmp /dev/null 2> /dev/nullif [ $? -eq 0 ]; then
# Character screen is showing so copy the screenshot
cp /tmp/d2screen.bmp charscreen.bmp
fisleep 0.3s
done
Hopefully this helps someone else in their hacking endeavors!