この記事はM5Stack Advent Calendarの12日目の記事です。
私が開発しているM5Stack用のライブラリです。液晶にかわいい顔を表示することができます。
https://github.com/meganetaaan/m5stack-avatar
今までのアバターは円や矩形などの図形の組み合わせでしかパーツを作れませんでしたが、 この記事ではビットマップ画像をアバターの顔パーツとして描画する方法を紹介します。
ビットマップをアバターの顔パーツにできた #M5Stack pic.twitter.com/9MI8y5cPhM
— ししかわ (@meganetaaan) December 7, 2018
XBM(XBitMap)は画像をC言語の配列として表現したファイル形式です。 ソースコードに埋め込んで利用できます。 バイナリイメージ(各ピクセルが白黒どちらか)専用です。
XBM形式への変換は次のようなWebアプリを使うのが最も手軽です。
https://www.online-utility.org/image/convert/to/XBM
または、開発環境にImageMagickをインストールしていれば、コマンド一発で変換できます。
1
$ convert input.png output.xbm
ここでは例として次の画像を変換してみましょう。
http://www.iconarchive.com/show/mono-general-4-icons-by-custom-icon-design/eye-icon.html
ImageMagickで変換しますが、このとき同時にアバターのパーツとして表示させたい大きさにリサイズします。 40x40ピクセルの場合は次のようになります。
1
$ convert eye.png -resize 40x40 eye_small.xbm
変換後のファイルは次のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
#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進数表記されているのがわかるかと思います。
前述のXBM画像をM5Stackのプログラムとして書き込むために、ファイルを少し修正する必要があります。
- ファイルをリネームして拡張子を.hにします
1
$mv eye_small.xbm eye_small.h
- 公式のサンプルコードを参考に、次のように書き換えます。
1 2 3 4 5
#include <pgmspace.h> #define eye_small_width 40 #define eye_small_height 40 PROGMEM const unsigned char eye_small[] = {/* 配列の中身はおなじため省略 */};
PROGMEMはデータを端末のフラッシュメモリ上に配置するためのキーワードです。 これでeye_small.hをインクルードすると画像が使えるようになります。
M5Stackの顔の各パーツはTFT_eSprite
クラスのメソッドを介して描画を行います。
XBM画像の描画はdrawXBitMap
メソッドでできます。
前述の画像を描画するコードをライブラリのサンプルとして公開しました。 サンプルから画像描画部分だけ抜き出すと次のようなイメージです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
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); } };
以上でアバターの顔パーツとして画像が描画できるようになります。 この機能を使えばかなり表現力が増すかと思います。ぜひあなただけのカスタムアバターを作ってみてください!