Posted at
M5StackDay 12

M5Stack Avatarでビットマップ画像の顔パーツを表示する

この記事はM5Stack Advent Calendarの12日目の記事です。


M5Stack Avatarとは

私が開発しているM5Stack用のライブラリです。液晶にかわいい顔を表示することができます。

https://github.com/meganetaaan/m5stack-avatar

今までのアバターは円や矩形などの図形の組み合わせでしかパーツを作れませんでしたが、

この記事ではビットマップ画像をアバターの顔パーツとして描画する方法を紹介します。


画像をXBM形式に変換する

XBM(XBitMap)は画像をC言語の配列として表現したファイル形式です。

ソースコードに埋め込んで利用できます。

バイナリイメージ(各ピクセルが白黒どちらか)専用です。

XBM形式への変換は次のようなWebアプリを使うのが最も手軽です。

https://www.online-utility.org/image/convert/to/XBM

または、開発環境にImageMagickをインストールしていれば、コマンド一発で変換できます。

$ convert input.png output.xbm

ここでは例として次の画像を変換してみましょう。

http://www.iconarchive.com/show/mono-general-4-icons-by-custom-icon-design/eye-icon.html

ImageMagickで変換しますが、このとき同時にアバターのパーツとして表示させたい大きさにリサイズします。

40x40ピクセルの場合は次のようになります。

$ convert eye.png -resize 40x40 eye_small.xbm

変換後のファイルは次のようになります。

#define eye_small_width 40

#define eye_small_height 40
static char eye_small_bits[] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0xFC, 0xFF, 0xFF, 0x07, 0x00,
0xE0, 0xFF, 0xFF, 0x01, 0x00, 0x80, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0xFE,
0x1F, 0x00, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x00,
0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x01, 0x00,
0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0x01, 0x00, 0x80, 0x01, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00,
0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0x00,
0xFE, 0xFF, 0x01, 0x00, 0x80, 0xFF, 0xFF, 0x07, 0x00, 0xE0, 0xFF, 0xFF,
0x3F, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, };

画像の1ピクセルが1ビットに対応しており、8ビット=1バイト毎に16進数表記されているのがわかるかと思います。


M5Stackからの読み込み

前述のXBM画像をM5Stackのプログラムとして書き込むために、ファイルを少し修正する必要があります。


  • ファイルをリネームして拡張子を.hにします

$mv eye_small.xbm eye_small.h

#include <pgmspace.h>


#define eye_small_width 40
#define eye_small_height 40
PROGMEM const unsigned char eye_small[] = {/* 配列の中身はおなじため省略 */};

PROGMEMはデータを端末のフラッシュメモリ上に配置するためのキーワードです。

これでeye_small.hをインクルードすると画像が使えるようになります。


M5Stack-Avatarを使った描画

M5Stackの顔の各パーツはTFT_eSpriteクラスのメソッドを介して描画を行います。

XBM画像の描画はdrawXBitMapメソッドでできます。

前述の画像を描画するコードをライブラリのサンプルとして公開しました。

サンプルから画像描画部分だけ抜き出すと次のようなイメージです。


class BMPEye : public Drawable
{
void draw(TFT_eSPI *spi, BoundingRect rect, DrawContext *ctx)
{
uint16_t color = ctx->getColorPalette()->get(COLOR_PRIMARY);
uint16_t cx = rect.getCenterX();
uint16_t cy = rect.getCenterY();
spi->drawXBitmap(
cx - eye_small_width / 2,
cy - eye_small_height / 2,
eye_small, eye_small_width, eye_small_height, color);
}
};

以上でアバターの顔パーツとして画像が描画できるようになります。

この機能を使えばかなり表現力が増すかと思います。ぜひあなただけのカスタムアバターを作ってみてください!