Re: Imagemagick deepzoom - tiling and resizing huge pictures
Posted: 2013-12-18T15:25:40-07:00
Okey, So I've written myself two shell scripts:
one to do the tiling of an image that has already been converted into the mpc format:
And another one that will do the scaling necessary to get a deep-zoom pyramid - and call the above script repeatedly to tile each layer:
update:
I've outsorced the functionality to find the right numbers for the pyramid-levels to an extra script, since I need floating point calculations for it:
one to do the tiling of an image that has already been converted into the mpc format:
Code: Select all
#!/bin/bash
#usage:
#./tile-mpc.sh wall2-right_merged_55697px.mpc 55697 871
mpcin=$1
picsize=$2
tilesize=$3
tiledir=$4
if [ -z ${tiledir+x} ]; then tiledir="tiles/"; fi
x=0
y=0
while [ $y -lt $picsize ]
do
ya=$[$y/871]
yl=$[$picsize-$y]
yl=$(($yl<871?$yl:871))
while [ $x -lt $picsize ]
do
xa=$[$x/871]
xl=$[$picsize-$x]
xl=$(($xl<871?$xl:871))
convert -limit memory 32 -limit map 32 $mpcin -crop $xl"x"$yl+$x+$y +repage $tiledir$xa"_"$ya.jpg
x=$[$x+871]
done
x=0
y=$[$y+871]
done
Code: Select all
#!/bin/bash
input=$1
tilesize=$2
if [ -z $tilesize ]; then tilesize=512; fi
skipfirsttile=$3
#dim=$(mediainfo --Output="Image;%Height%" $input)
dim=$(identify -format "%w" $input)
type=$(identify -format "%m" $input)
if [ $type = "MPC" ]
then
echo "good, input is already an MPC, we don't need to convert it"
mpc=$input
else
echo "will convert input image to MPC format before tiling"
mpc="${input%.*}"".mpc"
convert -verbose -monitor -limit memory 2G -limit map 4G $input $mpc
fi
lvl=$(./salado-level-calc.sh $dim)
if [ $skipfirsttile -eq 1 ]
then
echo "skipfirsttile parameter set, will continue with first resize operation now"
else
echo "tiling original image (lvl $lvl) now"
mkdir $lvl
./tile-mpc.sh $mpc $dim $tilesize "$lvl/"
fi
lvl=$[$lvl-1]
scale=2
mpcpre=$mpc
mpcl="${input%.*}""_lvl$lvl.mpc"
diml=$[$dim/$scale]
while [ $diml -gt $tilesize ]
do
echo "will resize for lvl $lvl with scale $scale -> edge length $diml into $mpcl now"
#for best quality, use $mpc as source, for faster processing, use $mpcpre
convert -verbose -monitor -limit memory 2G -limit map 4G "$mpcpre" -resize $diml"x"$diml "$mpcl"
echo "finished resize for lvl $lvl - will start tiling it now"
mkdir $lvl
./tile-mpc.sh $mpcl $diml $tilesize "$lvl/"
lvl=$[$lvl-1]
scale=$[$scale*2]
mpcpre=$mpcl
mpcl="${input%.*}""_lvl$lvl.mpc"
diml=$[$dim/$scale]
done
mkdir $lvl
convert -verbose -monitor -limit memory 2G -limit map 4G "$mpcpre" -resize $diml"x"$diml "$lvl/0_0.jpg"
I've outsorced the functionality to find the right numbers for the pyramid-levels to an extra script, since I need floating point calculations for it:
Code: Select all
#!/bin/bash
# Default scale used by float functions.
float_scale=2
#####################################################################
# Evaluate a floating point number expression.
function float_eval()
{
local stat=0
local result=0.0
if [[ $# -gt 0 ]]; then
result=$(echo "scale=$float_scale; $*" | bc -q 2>/dev/null)
stat=$?
if [[ $stat -eq 0 && -z "$result" ]]; then stat=1; fi
fi
echo $result
return $stat
}
#####################################################################
# Evaluate a floating point number conditional expression.
function float_cond()
{
local cond=0
if [[ $# -gt 0 ]]; then
cond=$(echo "$*" | bc -q 2>/dev/null)
if [[ -z "$cond" ]]; then cond=0; fi
if [[ "$cond" != 0 && "$cond" != 1 ]]; then cond=0; fi
fi
local stat=$((cond == 0))
return $stat
}
#####################################################################
# main script
dim=$1
scale=1
lvl=0
diml=$dim
while float_cond "$diml > 1"
do
#echo "$diml - $lvl"
scale=$[$scale*2]
diml=$(float_eval "$dim / $scale")
lvl=$[$lvl+1]
done
echo $lvl