Created
November 14, 2024 02:58
-
-
Save jemc/99e70b18d35b2ea9639fa1e9123aae34 to your computer and use it in GitHub Desktop.
Export BMFont definitions from Aseprite slices
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
set -e | |
# Given an Aseprite file containing pixel art font characters, with an | |
# Aseprite slice marking each character, export it as a .png file alongside an | |
# output BMFont .fnt file defining a font composed of those characters. | |
# | |
# Use environment variables to specify options, and pass the input Aseprite | |
# file itself as the only CLI argument. | |
# | |
# If you have an Aseprite file containing multiple fonts, you can export them | |
# one by one by specifying a `slice_prefix` to filter the slices by. | |
# | |
# If a `face` name is not specified, the font will be named based on the | |
# input Aseprite filename (and the `slice_prefix` if given). | |
# | |
# If an `out` path is not specified, the .fnt file will be saved alongside the | |
# input Aseprite file, with the same name (with added `slice_prefix` if given). | |
# | |
# The `.png` is always exported alongside the aseprite file with the same name | |
# (only the file extension changes). | |
# | |
# Information about the process is logged to stderr. | |
# The `.fnt` file is in a human-editable format, allowing for additional tweaks. | |
# The content of the `.fnt` file is also logged to stderr for visibility. | |
in="${in:-$1}" | |
if [ -z "$in" ]; then | |
echo "Usage: env [out=''] [face=''] [slice_prefix=''] $0 /path/to/input.aseprite" >&2 | |
exit 1 | |
fi | |
slice_prefix="${slice_prefix:-}" | |
face="${face:-${slice_prefix}$(basename "$in" .aseprite)}" | |
json_file="$(mktemp --suffix .json)" | |
png_file="$(dirname "$in")/$(basename "$in" .aseprite).png" | |
fnt_file="${out:-$(dirname "$in")/${slice_prefix}$(basename "$in" .aseprite).fnt}" | |
echo "Exporting $in file as png" > /dev/stderr | |
aseprite --batch "$in" --save-as "$png_file" | |
echo "Extracting slice data" > /dev/stderr | |
aseprite --batch --data "$json_file" --list-slices "$in" | |
line_height=$(cat "$json_file" | jq '[.meta.slices[].keys[0].bounds.h] | max + 1') | |
base_height=$(cat "$json_file" | jq '[.meta.slices[].keys[0].bounds.h] | min') | |
png_width=$(cat "$json_file" | jq ".meta.size.w") | |
png_height=$(cat "$json_file" | jq ".meta.size.h") | |
echo "Writing font data to ${fnt_file}" > /dev/stderr | |
echo > /dev/stderr | |
echo "info face=\"${face}\" size=${base_height} bold=0 italic=0 charset=\"\" unicode=0 stretchH=100 smooth=0 aa=1 padding=0,0,0,0 spacing=0,0 outline=0" | tee /dev/stderr > "$fnt_file" | |
echo "common lineHeight=${line_height} base=${base_height} scaleW=${png_width} scaleH=${png_height} pages=1 packed=0 alphaChnl=1 redChnl=0 greenChnl=0 blueChnl=0" | tee /dev/stderr >> "$fnt_file" | |
echo "page id=0 ${png_file}" | tee /dev/stderr >> "$fnt_file" | |
cat "$json_file" | jq --arg slice_prefix "$slice_prefix" -r '.meta.slices[] | select(.name | startswith($slice_prefix)) | "char id=\(.name[($slice_prefix | length):] | explode | .[-1]) x=\(.keys[0].bounds.x) y=\(.keys[0].bounds.y) width=\(.keys[0].bounds.w) height=\(.keys[0].bounds.h) xoffset=0 yoffset=0 xadvance=\(.keys[0].bounds.w) page=0 chnl=15"' | tee /dev/stderr >> "$fnt_file" | |
echo > /dev/stderr | |
echo "output fnt: ${fnt_file}" > /dev/stderr | |
echo "output png: ${png_file}" > /dev/stderr |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment