電子工作

マジョカアイリスの画像データをバイナリから抽出する。

経緯

マジョカアイリスという女児用の魔法のステッキがタカラトミーより販売されていたのですが、そのステッキの価格が大幅に下がり、喜んだ某オタクが細長い液晶ディスプレイが欲しいが為に大量に購入し、Twitterで流行したことが始まりです。


魔法×戦士 マジマジョピュアーズ! マジョカアイリス

↑これが今回の主役のステッキです。

どうやら作品中では、必殺級のアイテムらしいです。

画像ファイルの在り処

マジョカアイリスの基板に挿入されているSDカード内のフォルダ構成はこのようになっています。

SDカード直下にある「AB565.bin」というバイナリファイルに画像ファイルがまとめられています。

今回はLinuxコマンドを用いてバイナリを分割しrgb565形式からbmp形式に変換し、画像の抽出を行います。

スクリプト

抽出に使用したスクリプトはこの様になりました。

dd if=AB565.bin bs=4915200 count=1 > F640x48x80.bin
dd if=AB565.bin bs=1 skip=4915200 > F128x128x282.bin

split -b 61440 -a 3 -d F640x48x80.bin a
split -b 32768 -a 3 -d F128x128x282.bin b

for FILE in $(find . -type f -name 'a*' -print | sed 's/^\.\///')
do
    ffmpeg -vcodec rawvideo -f rawvideo -pix_fmt rgb565 -s 640x48 -i $FILE -vcodec bmp A$FILE.bmp
done

for FILE in $(find . -type f -name 'b*' -print | sed 's/^\.\///')
do
    ffmpeg -vcodec rawvideo -f rawvideo -pix_fmt rgb565 -s 128x128 -i $FILE -vcodec bmp B$FILE.bmp
done

mkdir 640x48pic 128x128pic
mv A*.bmp 640x48pic/
mv B*.bmp 128x128pic/
rm a* b* F*

ちょっとした解説

バイナリファイルの構造

RGB565形式で保存された画像データが並べられています。

細長い液晶用(640×48)画像が80枚、正方形の液晶用(128×128)画像が282枚の情報が含まれています。

コードの解説

画像のサイズで大まかにバイナリファイルの分割

dd if=AB565.bin bs=4915200 count=1 > F640x48x80.bin
dd if=AB565.bin bs=1 skip=4915200 > F128x128x282.bin

ここでは、「640×48の画像」のみのバイナリと「128×128の画像」のみのバイナリに分割をしています。

RGB565形式では、RGBがそれぞれ5bit、6bit、5bitの計16bitの情報量を持っています。つまり1画素辺り2byteの情報量です。

従って、640×48サイズの画像の情報量は「640x48x2」より61440byteとなります。

更に、640×48サイズの画像は80枚存在するので「61440×80」より4915200byteとなります。

よって、ファイル上部から4915200byteでバイナリファイルを分割することにより「640×48の画像」と「128×128の画像」に分けることができます。

個々の画像でバイナリを分割

split -b 61440 -a 3 -d F640x48x80.bin a
split -b 32768 -a 3 -d F128x128x282.bin b

前述の画像サイズの計算の要領で同様に計算を行うと、一枚あたりの画像サイズはそれぞれ、「640×48」は61440byte、「128×128」の画像は32768byteとなります。

それぞれのバイナリを一枚あたりの画像サイズで分割していけば個々の画像のバイナリを抽出出来るということです。

また、splitコマンドのオプションは以下の通りです。

オプション操作
-b単位にbyteを使用
-d分割したファイルに連番で名前を付ける
-aファイルに付ける連番の桁数指定

この時点でフォルダ内はこのような感じです。

RGB565形式のデータをビットマップ画像に変換

for FILE in $(find . -type f -name ‘a*’ -print | sed ‘s/^.\///’)
do
 ffmpeg -vcodec rawvideo -f rawvideo -pix_fmt rgb565 -s 640×48 -i $FILE -vcodec bmp A$FILE.bmp
done

ffmpegを用いてRGB565フォーマットのバイナリデータを扱いやすいビットマップ画像に変換します。

ここでは”a”から始まるファイルを探し、繰り返し処理ですべてのデータをビットマップ画像に変換しています。

その他

残りの処理では、「640×48の画像」と「128×128の画像」を格納するそれぞれのフォルダを作成して画像を移動し、作業中にできた大量の中間ファイルを一括削除しています。

抽出できた画像

さいごに

今回は某魔法少女ステッキのおもちゃのバイナリデータを扱いました。私個人、組み込まれたバイナリデータを操作することは未経験だったので、先駆者たちの情報を元に追証という形で作業を進めることは非常に勉強になりました。

後述の参考となった投稿をしてくださった先駆者や、面白いおもちゃを作ってくださったタカラトミーさんに感謝です。

参考にさせていただいた投稿

https://honeylab.hatenablog.jp/entry/2021/01/08/131422