Skip to content

Instantly share code, notes, and snippets.

@mgvez
Last active May 16, 2019 01:38
Show Gist options
  • Save mgvez/4032988 to your computer and use it in GitHub Desktop.
Save mgvez/4032988 to your computer and use it in GitHub Desktop.
Uses ImageMagick to generate spritesheets with transparency
#!/bin/bash
# inspired by https://gist.github.com/968653 (https://github.com/jaymzcd)
# uses imagemagick to create spritesheets out of all the PNG images in a folder.
# There will be 2 passes done:
# - with the default tiling as determined by imagemagick
# - with the tiling optimization attempt by this script so as to leave no padding
# It seems that IM does not always produce the best optmization in regard to image size
# so compare and use the one that fits best.
# The spritesheets produced will be:
# - a PNG with transparency (32bits)
# - a PNG without transparency channel, where the normally transparent parts show (24bit)
# - same as previous, but jpg format
# - a PNG containing only the transparency channel, all others (RGB) being empty
#jpg quality
if [ $1 ]
then
qual=$1"%";
else
qual="70%";
fi
#name of spritesheet files
if [ $2 ]
then
classname=$2;
else
classname="sprite";
fi
#the folder in which we put the spritesheets
dirName="spritesheets";
mkdir $dirName;
# the extension to iterate over for input files
ext=".png";
file=$(ls *$ext | head -1);
#calculate width of single sprite image
width=`identify -format "%[fx:w]" "$file"`;
height=`identify -format "%[fx:h]" "$file"`;
#number of sprite files
n=$( ls *$ext -1 | wc -l);
# attempt to find a rectangle that needs no padding, the largest possible
# as it seems png compresses better on large images rather than high ones
# from my tests, but this might need to be investigated further.
# Anyway, the dimension that IM gives by default is not always the optimal
# one with regard to filesize
pad=$n;
nx=$(echo "$n / 2 + 1" | bc);
while [ $nx -gt 1 -a $pad -gt 0 ]; do
let nx=nx-1;
curPad=$(echo "$n % $nx" | bc);
if [ $curPad -lt $pad ]
then
pad=$curPad;
fi
done
tilingPasses=("0" $nx"x");
FILES=$(ls *$ext | sort -n | tr '\n' ' ');
for i in $(seq 0 $((${#tilingPasses[*]} - 1))); do
tiling=${tilingPasses[$i]};
subDirName="tiling-"$tiling;
mkdir $dirName/$subDirName;
echo "Generating 32 bits sprite (with alpha) tile "$tiling;
montage -alpha Set -background none -tile $tiling -geometry +0+0 \
${FILES[@]} PNG32:$dirName/$subDirName/$classname"-complete.png";
echo "Generating 24 bits sprite (without alpha, png) tile "$tiling;
montage -alpha Deactivate -tile $tiling -geometry +0+0 \
${FILES[@]} PNG32:$dirName/$subDirName/$classname".png";
echo "Generating 24 bits sprite (without alpha, jpg) tile "$tiling;
montage -alpha Deactivate -tile $tiling -geometry +0+0 -quality $qual \
${FILES[@]} $dirName/$subDirName/$classname".jpg";
echo "Generating 32 bits sprite of alpha only, tile "$tiling;
convert <(montage -background none -alpha Set -tile $tiling -geometry +0+0 ${FILES[@]} miff:-) \
-alpha off -fill black -colorize 100% -alpha on \
PNG32:$dirName/$subDirName/$classname"-alpha.png";
done;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment