概要
Asepriteで縦横サイズが2のべき乗値のPNGファイルを出力するにあたって調べたことをまとめる。
この記事執筆時のAsepriteのバージョンはv1.2.25-x64である。
背景
Asepriteはコマンドラインインターフェース(CLI)を持っていて、コマンドを叩くことでAseprite専用の.aseprite
ファイルからPNGファイルに出力したり、フレームの情報(UV位置やフレームの時間間隔)をJSONファイルに出力したりできる。
1枚の画像の上に複数のフレームのデータを並べたテクスチャをドットバイドットで描画するためには、テクスチャの縦横のサイズを2のべき乗(2,4,8,16,32,...)の値にしないといけないらしい(参考: このページの下のほう)。AsepriteのCLIのオプションに出力画像サイズを2のべき乗値にするオプションがあれば便利なのだが、そのようなオプションは現状は無いみたいである(参考: AsepriteのCLIのドキュメント)。このオプションを実装してほしいという旨はGitHubのIssueには上がっているのでそのうち実装されるかもしれないが、とにかく現在は無い。その代わり出力画像ファイルの縦横の大きさを指定するオプションがあったので、こちらを用いて解決できた。
具体的な解決法
- とりあえずAseprite CLIを用いて出力画像のサイズを得る
- 出力画像サイズから2のべき乗値を計算する
- Aseprite CLIで出力画像の縦横の大きさを2のべき乗値に指定して画像出力
Aseprite CLIを用いて出力画像のサイズを得る
Aseprite.exe -b --data hoge.json --sheet-pack hoge.aseprite
-
-b
: GUIを表示しないようにするオプション。 -
--data
: 出力JSONファイル名を指定するオプション。 -
--sheet-pack
: スプライトシートの並べ方を指定するオプション。
このコマンドを実行すると出力画像サイズが入ったJSONファイルを出力してくれる。このJSONファイルを解析して出力画像サイズを得る。画像サイズはJSON内の meta/size
に格納されている。
出力画像ファイル名を指定する--sheet
オプションを指定しないことで、JSONファイルのみを出力している。
出力画像サイズから2のべき乗値を計算する
def get_msb(x: int) -> int:
assert x > 0
msb = 0
while True:
x >>= 1
if x == 0:
return msb
msb += 1
def fix_to_power2(x: int) -> int:
mask = (1 << get_msb(x)) - 1
x += mask
return x & (~mask)
上記のfix_to_power2
関数で変換できる。この関数は入力以上の一番近い2のべき乗値を返す関数である。入出力の例は下表を参照。※筆者はPythonは不慣れなのでPythonらしくなかったりは許してください。
入力 | 出力 |
---|---|
127 | 128 |
128 | 128 |
129 | 256 |
追記
上記のfix_to_power2
関数について @shiracamus さんから改善のコメントをいただきました。こちらのほうが分かりやすい! ありがとうございます!!
# 修正版
def fix_to_power2(x: int) -> int:
return 1 << (x - 1).bit_length()
Aseprite CLIで出力画像の縦横の大きさを指定して出力
--sheet-width
、--sheet-height
オプションを用いて出力画像の縦横を指定する。
Aseprite.exe -b --data hoge.json --sheet hoge.png --sheet-pack --list-tags --format json-array --sheet-width <先ほど計算した値> --sheet-height <先ほど計算した値> hoge.aseprite
-
--sheet
: 出力画像ファイル名を指定する -
--list-tags
: タグ情報を付加する (この記事の本筋とは関係ない) -
--format
: JSONの出力形式を指定する (この記事本筋とは関係ない) --sheet-width
: 出力画像の横幅を指定--sheet-height
: 出力画像の縦幅を指定
感想
ここに書いたこと+Makefileとかでうまいことやりたいですねえ。