So it turns out now the most tedious thing to do when creating the maps is renaming the files with their tile position information. I’m not a fan of tedious.
I figured Imagemagick’s -subimage recognition might be the way to go and went as far as writing a script that could pull out the maps from screenshots and (assuming I only ever fed it properly named files) snag off the 6 character file prefix to preserve as the file name.
Once I had some example subimages to compare my screen shots to, I ran a test of the compare.
compare -metric MAE -subimage-search 29-12-2014_08.52.24.png ./cnrkeys/07y07x_cnrkey.png null: 2>&1
After 10 minutes of letting that process run in the background I did some more research on subimage-search and why it might be sooooooo sloooowwwwww. It turns out compare is trying to find all best possible matches. I can’t limit where ImageMagick will to look without cropping the main image in the exactly same way. Another recommendation beside croping would be to downsample them both. A combination downsample and crop would be the fastest of all.
Since that kind of multistep processing seemed like overkill for my problem, I changed tactics. I just need to know if a certain spot on the screen is green. If the pixel is green then I am in the corresponding location.
#What color on the legend indicates where I am. #This result will be based on the formatting used below. TRUECOLOR="136,216,0" #Get one pixel XCORD,YCORD in from the top left and spit out its #color information in the format requested. mycolor=$(convert $p[1x1+${XCORD}+${YCORD}] -format "%[fx:floor(255*u.r)],%[fx:floor(255*u.g)],%[fx:floor(255*u.b)]" info:-) #An example of what to do with the information if [ "$mycolor" == "$TRUECOLOR" ]; then found=1 fi
Took a little doing, but I got it working with a row-column scan (gist shown at the end). With a few changes I can use a very similar script to see if Link is dead, what weapon is enabled… it all depends on figuring out a unique pixel color at a unique location. It is still slow, about 2 to 10 seconds per image depending on its position. To recognize location 07y15x convert will be called 128 times. It would be faster processing time wise to figure out a way to load a pixel array, but not, it think, faster in people time. I’m not doing millions of these suckers.
As a bonus I can have the script generate my travel route. Seems handy. Not sure how I’ll use it yet.
Current Process
- Organize the potential images I want to use for the map (include duplicates if I went through and area twice) in iPhoto or in Finder.
- Run the rename script on the folder
- Cull the duplicates for any tile position
- Run the map-making script on the folder
I do the rename script after organizing now because it changes the order they get processed in and I am thinking about how to preserve route information.
#!/bin/bash | |
#Reduce time by running process for just the part of the | |
#grid actually represented | |
Y1=$1 | |
Y2=$2 | |
X1=$3 | |
X2=$4 | |
#used in prefix generation | |
ZPAD=2 | |
#folder files saved into | |
MYDIR="named_tiles" | |
#About the image being processed and where to look | |
#on the legend for the location information. | |
#How far from the top left corner | |
XOFFSET=193 | |
YOFFSET=90 | |
#How big of an area am I searching from that offset? | |
let KEYWIDTH=497-$XOFFSET | |
let KEYHEIGHT=210-$YOFFSET | |
#How many possible tiles represented in that region? | |
NUM_X_POS=16 #how many tiles wide? | |
NUM_Y_POS=8 #how many tiles tall? | |
#How big will each tiles representative area be? | |
let XMULTIPLIER=${KEYWIDTH}/${NUM_X_POS} | |
let YMULTIPLIER=${KEYHEIGHT}/${NUM_Y_POS} | |
#Look in the middle of that area. | |
let XOFFSET=XOFFSET+XMULTIPLIER/2 | |
let YOFFSET=YOFFSET+YMULTIPLIER/2 | |
#What color on the legend indicates where I am. | |
#This result will be based on the formating used below. | |
TRUECOLOR="136,216,0" | |
#Some variables needed to generate the route from I took if all | |
#my origin, which is not the top left. | |
#Will only work if the files are from the same day. | |
NL=$'\n' | |
MYROUTE="MY ROUTE:$NL" | |
ROUTEX=7 #if not far left tile, 0, then where? | |
ROUTEY=7 #if not top tile, 0, then where? | |
#The defaults if no variables are passed into the script. | |
if [[ -z $Y1 ]]; then Y1=0 ; fi | |
if [[ -z $Y2 ]]; then let Y2=${NUM_Y_POS}-1 ; fi | |
if [[ -z $X1 ]]; then X1=0 ; fi | |
if [[ -z $X2 ]]; then let X2=${NUM_X_POS}-1 ; fi | |
if [ ! -d ./${MYDIR} ]; then mkdir ./${MYDIR}; fi | |
#————– START LOOP ———————-# | |
# If there are PNG files… get them. | |
if ls | grep png; then for p in *.png; do | |
echo "Processing $p" | |
found=0 | |
#Begin row-col scan with first row. | |
for i in $(seq $Y1 $Y2); do | |
let YCORD=${YOFFSET}+${i}*${YMULTIPLIER} | |
#FOR ROUTE TEXT | |
let YLOC=ROUTEY-${i} | |
#Begin col scan with first col | |
for j in $(seq $X1 $X2); do | |
let XCORD=${XOFFSET}+${j}*${XMULTIPLIER} | |
#FOR ROUTE TEXT | |
let XLOC=ROUTEX-${j} | |
if [ "$XLOC" -ge 0 ] | |
then XDESC="E" | |
else XDESC="W" | |
fi | |
XLOC=${XLOC#-} | |
#The format of this line should match pattern of TRUECOLOR. | |
mycolor=$(convert $p[1×1+${XCORD}+${YCORD}] -format "%[fx:floor(255*u.r)],%[fx:floor(255*u.g)],%[fx:floor(255*u.b)]" info:-) | |
#echo "I look $mycolor at $XCORD, $YCORD" | |
if [ "$mycolor" == "$TRUECOLOR" ]; then | |
found=1 | |
#FOR ROUTE TEXT | |
printf -v location "%0*dN, %0*d%s" $ZPAD $YLOC $ZPAD $XLOC $XDESC | |
MYROUTE="${MYROUTE}${location}$NL" | |
#echo "I am at $location" | |
#FILE RENAME AND MOVE | |
printf -v fileprefix "%0*dy%0*dx" $ZPAD $i $ZPAD $j | |
#copy the file while preserving timestamps | |
cp -p $p ./${MYDIR}/${fileprefix}_${p} | |
#echo "I am at $filename" | |
break 2 | |
fi | |
done | |
done | |
#If I don't belong anywhere… Death images will trigger this. | |
if [ "$found" -lt 1 ] | |
then | |
cp -p $p ./${MYDIR}/HELP_${p} | |
fi | |
done | |
fi | |
#—————— END LOOP ————————# | |
#Save the route to file. | |
#Will only work if complete sequence runs. That is a | |
#feature for now. | |
echo "$MYROUTE" > route.txt |