The idea of cropping the mask itself based on the original image size did work, and was incomparably simpler than the "second version". I haven't yet made it clean the temporary files, and perhaps there are some declarations of variables that aren't even being used, leftovers from earlier attempts, with different logic. But it works...
Code: Select all
#!/bin/bash
convert montage.png -crop 220x220 +repage maskplain-%02d.png
\ls -1 *.jpg > originals.txt
\ls -1 maskplain*.png > masks.txt
while read original <&3 && read mask <&4 ; do
res=($(identify -format "%w %h" {$original}))
x=${res[0]}
y=${res[1]}
if ((x>y)) ; then
ycrop=$(((x/2)-(y/2)))
xcrop=0
else
xcrop=$(((y/2)-(x/2)))
ycrop=0
fi
samplevar="${x}x"
((y>x)) && samplevar="x${y}"
unset cropmask
if ! ((x==y)) ; then
cropmaskvar="${x}x${y}+$xcrop+$ycrop"
cropmask="-crop $cropmaskvar"
fi
convert ${mask} -colorspace gray -background white -alpha remove -threshold 99% -sample ${samplevar} $cropmask +repage /dev/shm/masktmp-${original}.gif
cropv=`convert /dev/shm/masktmp-${original}.gif -format "%@" info:` ;
#convert "${original}" -crop $cropv +repage "${original/.jpg/-cropped.jpg}"
# I have found that for the final crop, jpegtran does an incomparably faster job than imagemagick. This line will attempt first to do a lossless cropping, and proceed to a normal cropping, if it fails.
jpegtran -perfect -crop $cropv "${original}" > "${original/.jpg/-cropped.jpg}" || jpegtran -crop $cropv "${original}" > "${original/.jpg/-cropped.jpg}"
done 3<originals.txt 4<masks.txt
(There was yet another instance of "convert" subprocess that was apparently unnecessary.)
Suggestion, In order to make the computer (or old computers) still usable while it's working with big images: adding early on the script:
And replacing all the following instances of "convert" to "$convert".
Additionally I have every convert line ending like this:
Which requires the "cpulimit" to be installed, less common than ionice, which I believe is a standard thing.