Skip to content

Instantly share code, notes, and snippets.

@SuperFromND
Created April 7, 2026 18:49
Show Gist options
  • Select an option

  • Save SuperFromND/2c58d48d2a1eeff67fe27961620338e8 to your computer and use it in GitHub Desktop.

Select an option

Save SuperFromND/2c58d48d2a1eeff67fe27961620338e8 to your computer and use it in GitHub Desktop.
Bash: Key of Avalon Photoscans to Cropped Cards Script
#!/bin/bash
# Card cropping script for Key of Avalon card scans
# Requires Bash and a recent-ish version of ImageMagick (tested with 7.0.8-3)
# CC0/WTFPL/equivalent Public Domain license. Do whatever you want with this!
# Written by SuperFromND, 2026.
mkdir front
mkdir back
# input is expected to be PNG files in the same directory as this script
# the scans are expected to be four cards placed in the corners of the scanner, all facing the same direction
# filenames expected to follow the scheme: "Card 1_Card 2_Card 3_Card 4_F.png"
# where "Card 1" through "Card 4" are the card's names in top-to-bottom- left-to-right order
# and "F" or "B" at the end to indicate whether this is the front or back of the card
# all separated by underscore characters ("_")
# if you have a scan with less than 4 cards, you can use "NULL" as a name to skip it
for file in *.png; do
# weird looking chars are just ANSI escapes, makes the line cyan :]
# easier to see when viewing script output on a terminal or w/e lol
printf "\033[0;36mProcessing: $file \033[0m\n"
# splits filename into an array of the card names, plus the suffix for card orientation
IFS='_' read -ra cards <<< "${file%.*}"
for i in "${cards[@]}"; do
if [ "$i" == "${cards[-1]}" ]; then
: # skips the last array member ("F" or "B")
elif [ "$i" == "NULL" ]; then
# allows skipping blank areas for scans that have less than 4 cards
echo "Skipping a null card..."
else
# adjust these for final resolution if the cards end up not fitting
WIDTH=751
HEIGHT=1030
XOFF=0
YOFF=0
# adjust these if the cards are too off-center
case "$i" in
"${cards[0]}") XOFF=104; YOFF=100;
;;
"${cards[1]}") XOFF=1743; YOFF=100;
;;
"${cards[2]}") XOFF=100; YOFF=2369;
;;
"${cards[3]}") XOFF=1743; YOFF=2369;
;;
esac
# magick syntax for a crop command is "WxH+X+Y"
DIMS="$WIDTH""x""$HEIGHT""+""$XOFF""+""$YOFF"
# default folder location, just in case something goes awry (misnamed input, etc)
FOLDER="./front/"
if [ "F" == "${cards[-1]}" ]; then FOLDER="./front/"; fi
if [ "B" == "${cards[-1]}" ]; then FOLDER="./back/"; fi
# constructs a path like "./front/Card 1-F.png"
FNAME="$FOLDER""$i""-""${cards[-1]}"".png"
echo "Saving to: $FNAME"
# "-level" lowers the brightness a bit since scanners tend to wash out the brightness slightly
magick "$file" -crop "$DIMS" -level 19%,100% "$FNAME"
fi
done
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment