Skip to content

Instantly share code, notes, and snippets.

@yszheda
Created December 9, 2015 11:48
Show Gist options
  • Save yszheda/7df8255c97064a6bfee3 to your computer and use it in GitHub Desktop.
Save yszheda/7df8255c97064a6bfee3 to your computer and use it in GitHub Desktop.
generate BMFont from a set of pngs
#!/bin/bash
if [ $1 == "-h" ]; then
echo "Usage: "
echo "$(basename $0) <inputPath> <prefix>"
echo "generate png and fnt under <inputPath>/output"
echo "<inputPath>: path containing images"
echo "<prefix>: prefix of output file names"
exit 0
fi
inputPath=$1
prefix=$2
outputPath="./output"
if [[ $3 ]]; then
outputPath = $3
fi
localPngFile=${prefix}.png
pngFile=${outputPath}/${localPngFile}
fntFile=${outputPath}/${prefix}.fnt
pngFileList=($(ls ${inputPath} | grep png | sort))
charWidth=$(ls ${inputPath} | grep png | head -1 | xargs file | awk -F',' '{print $2}'| awk '/x/{print $1}')
charHeight=$(ls ${inputPath} | grep png | head -1 | xargs file | awk -F',' '{print $2}'| awk '/x/{print $3}')
imageNum=$(find ${inputPath} -d 1 -name "*.png" | wc -l)
# remove leading whitespace
shopt -s extglob
imageNum=${imageNum##*( )}
shopt -u extglob
clean ()
{
if [[ -d ${outputPath} ]]; then
rm ${outputPath}/*
else
mkdir ${outputPath}
fi
}
mergePngs ()
{
if ! type convert > /dev/null; then
echo "You need to install [ImageMagic](http://www.imagemagick.org/)."
else
# ls ${inputPath} | grep png | sort | tr '\n' ' ' | xargs -J % convert % +append ${pngFile}
find ${inputPath} -d 1 -name "*.png" | sort | tr '\n' ' ' | xargs -J % convert % +append ${pngFile}
fi
}
##################################################
# Reference Document:
# http://www.angelcode.com/products/bmfont/doc/file_format.html
##################################################
# info: This tag holds information on how the font was generated.
##################################################
# face This is the name of the true type font.
face="Arial"
# size The size of the true type font.
size=32
# bold The font is bold.
bold=0
# italic The font is italic.
italic=0
# charset The name of the OEM charset used (when not unicode).
charset=""
# unicode Set to 1 if it is the unicode charset.
unicode=0
# stretchH The font height stretch in percentage. 100% means no stretch.
stretchH=100
# smooth Set to 1 if smoothing was turned on.
smooth=1
# aa The supersampling level used. 1 means no supersampling was used.
aa=1
# padding The padding for each character (up, right, down, left).
paddingUp=0
paddingRight=0
paddingDown=0
paddingLeft=0
# spacing The spacing for each character (horizontal, vertical).
spacingH=0
spacingV=0
# outline The outline thickness for the characters.
outline=0
##################################################
# common: This tag holds information common to all characters.
##################################################
# lineHeight This is the distance in pixels between each line of text.
lineHeight=${charHeight}
# base The number of pixels from the absolute top of the line to the base of the characters.
base=${charHeight}
# scaleW The width of the texture, normally used to scale the x pos of the character image.
scaleW=256
# scaleH The height of the texture, normally used to scale the y pos of the character image.
scaleH=256
# pages The number of texture pages included in the font.
pages=1
# packed Set to 1 if the monochrome characters have been packed into each of the texture channels. In this case alphaChnl describes what is stored in each channel.
packed=0
# alphaChnl Set to 0 if the channel holds the glyph data, 1 if it holds the outline, 2 if it holds the glyph and the outline, 3 if its set to zero, and 4 if its set to one.
alphaChnl=1
# redChnl Set to 0 if the channel holds the glyph data, 1 if it holds the outline, 2 if it holds the glyph and the outline, 3 if its set to zero, and 4 if its set to one.
redChnl=0
# greenChnl Set to 0 if the channel holds the glyph data, 1 if it holds the outline, 2 if it holds the glyph and the outline, 3 if its set to zero, and 4 if its set to one.
greenChnl=0
# blueChnl Set to 0 if the channel holds the glyph data, 1 if it holds the outline, 2 if it holds the glyph and the outline, 3 if its set to zero, and 4 if its set to one.
blueChnl=0
##################################################
# page: This tag gives the name of a texture file. There is one for each page in the font.
##################################################
# id The page id.
id=0
# file The texture file name.
file=${localPngFile}
##################################################
# char: This tag describes on character in the font. There is one for each included character in the font.
##################################################
# id The character id.
# x The left position of the character image in the texture.
# y The top position of the character image in the texture.
y=0
# width The width of the character image in the texture.
width=${charWidth}
# height The height of the character image in the texture.
height=${charHeight}
# xoffset How much the current position should be offset when copying the image from the texture to the screen.
xoffset=0
# yoffset How much the current position should be offset when copying the image from the texture to the screen.
yoffset=0
# xadvance How much the current position should be advanced after drawing the character.
xadvance=${charWidth}
# page The texture page where the character image is found.
page=0
# chnl The texture channel where the character image is found (1 = blue, 2 = green, 4 = red, 8 = alpha, 15 = all channels).
chnl=15
##################################################
# kerning: The kerning information is used to adjust the distance between certain characters, e.g. some characters should be placed closer to each other than others.
##################################################
# first The first character id.
# second The second character id.
# amount How much the x position should be adjusted when drawing the second character immediately following the first.
##################################################
writeInfo ()
{
echo "info face=\"${face}\" size=${size} bold=${bold} italic=${italic} charset=\"${charset}\" unicode=${unicode} stretchH=${stretchH} smooth=${smooth} aa=${aa} padding=${paddingUp},${paddingRight},${paddingDown},${paddingLeft} spacing=${spacingH},${spacingV} outline=${outline}"
echo "info face=\"${face}\" size=${size} bold=${bold} italic=${italic} charset=\"${charset}\" unicode=${unicode} stretchH=${stretchH} smooth=${smooth} aa=${aa} padding=${paddingUp},${paddingRight},${paddingDown},${paddingLeft} spacing=${spacingH},${spacingV} outline=${outline}" >> ${fntFile}
}
writeCommon ()
{
echo "common lineHeight=${lineHeight} base=${base} scaleW=${scaleW} scaleH=${scaleH} pages=${pages} packed=${packed} alphaChnl=${alphaChnl} redChnl=${redChnl} greenChnl=${greenChnl} blueChnl=${blueChnl}"
echo "common lineHeight=${lineHeight} base=${base} scaleW=${scaleW} scaleH=${scaleH} pages=${pages} packed=${packed} alphaChnl=${alphaChnl} redChnl=${redChnl} greenChnl=${greenChnl} blueChnl=${blueChnl}" >> ${fntFile}
}
writePage ()
{
echo "page id=${id} file=\"${file}\""
echo "page id=${id} file=\"${file}\"" >> ${fntFile}
}
writeChars ()
{
echo "chars count=${imageNum}"
echo "chars count=${imageNum}" >> ${fntFile}
declare -i i=0
for file in "${pngFileList[@]}"
do
letter=$(echo ${file} | cut -d'.' -f 1 | tail -c 2)
id=$(printf '%d' "'${letter}")
let "x = charWidth * i"
echo "char id=${id} x=${x} y=${y} width=${width} height=${height} xoffset=${xoffset} yoffset=${yoffset} xadvance=${xadvance} page=${page} chnl=${chnl}"
echo "char id=${id} x=${x} y=${y} width=${width} height=${height} xoffset=${xoffset} yoffset=${yoffset} xadvance=${xadvance} page=${page} chnl=${chnl}" >> ${fntFile}
let "i += 1"
done
}
clean
mergePngs
touch ${fntFile}
writeInfo
writeCommon
writePage
writeChars
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment