M5Stick-Cに画像を表示する方法を簡潔に、デモコードと共に紹介します。今回紹介する方法は2つ。①ヘッダファイルに変換して読み込む②SPIFFS領域に直接画像を送り込んで読み込み表示する です。
動いている様子
今回は2パターンの画像表示方法を紹介します。
参考にしたサイト
方法①-画像をコードに変換して描画
-
Lang-shipさんの画像コード変換サイトにて、好きな画像を変換する。※M5stick-Cの解像度は80×160なので、それ以下の大きさに加工しておく
-
出力データをメモ帳などに貼り付け、拡張子を”.h”にして保存
-
以下の.inoファイルと同じフォルダに画像ファイル(.h)を移動。ここではlogo.h
という画像ファイル名にしました。
#include <M5StickC.h> // M5StickCの読み込み
// イメージデータ
#include "logo.h" // 画像データの読み込み
void setup() {
M5.begin();
M5.Axp.ScreenBreath(10);
M5.Lcd.setRotation(3);
M5.Lcd.setSwapBytes(false);
}
void loop() {
M5.Lcd.startWrite();
M5.Lcd.pushImage(0, 0, imgWidth, imgHeight, img);
// 描画終了
M5.Lcd.endWrite();
// Wait
delay(1000);
}
- M5stick-Cに書き込んで完成!
これだけで冒頭で紹介したような画像表示ができます。ただ、このままでは画像を.hファイルに変換しないといけなく若干面倒です。
方法②-画像ファイルとしてSPIFFSにアップロードして描画
M5Stick-Cを駆動しているESP32にはSPIFFS領域と呼ばれるファイル領域が用意されています。フラッシュの一部をUSBメモリみたいに使用できるイメージです。
ここに画像ファイルのままアップロードして、表示する方法を紹介します。
-
画像ファイルをビットマップ形式(.bmp)で保存。24ビットで保存しましょう。
-
以下のコードを用意して、.ino形式で保存しフォルダを作成
#include "FS.h"
#include "SPIFFS.h"
#include "M5StickC.h"
#include "M5Display.h"
//ここから参考にしたM5stackの関数群
uint16_t read16(fs::File &f) {
uint16_t result;
((uint8_t *)&result)[0] = f.read(); // LSB
((uint8_t *)&result)[1] = f.read(); // MSB
return result;
}
uint32_t read32(fs::File &f) {
uint32_t result;
((uint8_t *)&result)[0] = f.read(); // LSB
((uint8_t *)&result)[1] = f.read();
((uint8_t *)&result)[2] = f.read();
((uint8_t *)&result)[3] = f.read(); // MSB
return result;
}
void drawBmpFile(fs::FS &fs, const char *path, uint16_t x, uint16_t y) {
if ((x >= 160) || (y >= 80)) return;
// Open requested file on SD card
File bmpFS = fs.open(path, "r");
if (!bmpFS) {
Serial.print("File not found");
return;
}
uint32_t seekOffset;
uint16_t w, h, row, col;
uint8_t r, g, b;
uint32_t startTime = millis();
if (read16(bmpFS) == 0x4D42) {
read32(bmpFS);
read32(bmpFS);
seekOffset = read32(bmpFS);
read32(bmpFS);
w = read32(bmpFS);
h = read32(bmpFS);
if ((read16(bmpFS) == 1) && (read16(bmpFS) == 24) && (read32(bmpFS) == 0)) {
y += h - 1;
M5.Lcd.setSwapBytes(true);
bmpFS.seek(seekOffset);
uint16_t padding = (4 - ((w * 3) & 3)) & 3;
uint8_t lineBuffer[w * 3 + padding];
for (row = 0; row < h; row++) {
bmpFS.read(lineBuffer, sizeof(lineBuffer));
uint8_t* bptr = lineBuffer;
uint16_t* tptr = (uint16_t*)lineBuffer;
// Convert 24 to 16 bit colours
for (col = 0; col < w; col++) {
b = *bptr++;
g = *bptr++;
r = *bptr++;
*tptr++ = ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
}
// Push the pixel row to screen, pushImage will crop the line if needed
// y is decremented as the BMP image is drawn bottom up
M5.Lcd.pushImage(x, y--, w, 1, (uint16_t*)lineBuffer);
}
Serial.print("Loaded in "); Serial.print(millis() - startTime);
Serial.println(" ms");
}
else Serial.println("BMP format not recognized.");
}
bmpFS.close();
}
//参考にした関数終わり
void setup(){
M5.begin();
M5.Axp.ScreenBreath(12); // 7-12で明るさ設定
M5.Lcd.setRotation(3); // 0-3で画面の向き
if(!SPIFFS.begin(true)){
Serial.println("SPIFFS Mount Failed");
return;
}
drawBmpFile(SPIFFS, "/logo.bmp", 0, 0);
}
void loop(){
delay(1);
}
M5Stick-Cのライブラリにはファイルシステム(SDやSPIFFS)から画像を読み込んで表示する関数がありません(M5stackにはあります)。そこでM5stackのdrawBitmapFileを参考にして、drawBitmapFile関数を実装してみました。この関数部分を抜くと以下のコードだけになります。
#include "FS.h"
#include "SPIFFS.h"
#include "M5StickC.h"
#include "M5Display.h"
void setup(){
M5.begin();
M5.Axp.ScreenBreath(12); // 7-12で明るさ設定
M5.Lcd.setRotation(3); // 0-3で画面の向き
if(!SPIFFS.begin(true)){
Serial.println("SPIFFS Mount Failed");
return;
}
drawBmpFile(SPIFFS, "/logo.bmp", 0, 0);
}
void loop(){
delay(1);
}
-
作ったスケッチのフォルダ内にdata
という名前のフォルダを作り、その中に先程の.bmpファイルを入れます。※このフォルダ内が丸ごとM5Stick-Cにアップロードされます。
-
mgo-tecさんのSPIFFS uploaderの導入方法に従いSPIFFS uploaderを入れる
-
ESP32 Sketch Data Upload
を選択してM5Stick-Cにデータをアップロードする。
-
通常通りスケッチを書き込む
-
完成!
手順が多いように見えますが、画像をそのまま使えるので結果として楽じゃないかなと思います。(.hファイルだと書き込みが1回で済むのは楽)
まとめ
2つの方法を紹介しました。
- ヘッダファイルに変換して読み込む
- 画像をそのままSPIFFS領域にアップロードして読み込む
好みに合わせて使ってみて下さい!
M5Stick-Cに画像を表示する方法を簡潔に、デモコードと共に紹介します。今回紹介する方法は2つ。①ヘッダファイルに変換して読み込む②SPIFFS領域に直接画像を送り込んで読み込み表示する です。
目次
動いている様子
今回は2パターンの画像表示方法を紹介します。
参考にしたサイト
方法①-画像をコードに変換して描画
Lang-shipさんの画像コード変換サイトにて、好きな画像を変換する。※M5stick-Cの解像度は80×160なので、それ以下の大きさに加工しておく
出力データをメモ帳などに貼り付け、拡張子を”.h”にして保存
以下の.inoファイルと同じフォルダに画像ファイル(.h)を移動。ここでは
logo.h
という画像ファイル名にしました。これだけで冒頭で紹介したような画像表示ができます。ただ、このままでは画像を.hファイルに変換しないといけなく若干面倒です。
方法②-画像ファイルとしてSPIFFSにアップロードして描画
M5Stick-Cを駆動しているESP32にはSPIFFS領域と呼ばれるファイル領域が用意されています。フラッシュの一部をUSBメモリみたいに使用できるイメージです。
ここに画像ファイルのままアップロードして、表示する方法を紹介します。
画像ファイルをビットマップ形式(.bmp)で保存。24ビットで保存しましょう。
以下のコードを用意して、.ino形式で保存しフォルダを作成
M5Stick-Cのライブラリにはファイルシステム(SDやSPIFFS)から画像を読み込んで表示する関数がありません(M5stackにはあります)。そこでM5stackのdrawBitmapFileを参考にして、drawBitmapFile関数を実装してみました。この関数部分を抜くと以下のコードだけになります。
作ったスケッチのフォルダ内に
data
という名前のフォルダを作り、その中に先程の.bmpファイルを入れます。※このフォルダ内が丸ごとM5Stick-Cにアップロードされます。mgo-tecさんのSPIFFS uploaderの導入方法に従いSPIFFS uploaderを入れる
ESP32 Sketch Data Upload
を選択してM5Stick-Cにデータをアップロードする。通常通りスケッチを書き込む
完成!
手順が多いように見えますが、画像をそのまま使えるので結果として楽じゃないかなと思います。(.hファイルだと書き込みが1回で済むのは楽)
まとめ
2つの方法を紹介しました。
好みに合わせて使ってみて下さい!