diff --git a/src/content/blog-metas/2024-12-23-m5stack.json b/src/content/blog-metas/2024-12-23-m5stack.json new file mode 100644 index 0000000..b97317b --- /dev/null +++ b/src/content/blog-metas/2024-12-23-m5stack.json @@ -0,0 +1,3 @@ +{ + "postDate": "2024-12-26T11:27:15.913Z" +} diff --git a/src/content/blogs/2024-12-23-m5stack.md b/src/content/blogs/2024-12-23-m5stack.md new file mode 100644 index 0000000..be09d9d --- /dev/null +++ b/src/content/blogs/2024-12-23-m5stack.md @@ -0,0 +1,199 @@ +--- +title: M5StackでLCDに画像を表示する +description: M5StackでLCDに画像を表示する方法は複数ある。それぞれの紹介と簡単な比較をする。 +author: talkie +category: tech +tags: + - advent-calendar +--- + +この記事は [OUCC Advent Calendar 2024](https://adventar.org/calendars/10655) の23日目の記事です。 + +M5StackでLCDに画像を表示する方法についてM5Stackの公式ドキュメントをもとにまとめてみました。 + +## 使用する環境 +- PlatformIO for VScode +- M5Unified 0.2.2 +- M5Stack Basic + +## 基本的なコード +以下のコードがM5StackでLCDに画像を表示させる基本的なコードです。最後の関数を変更することで画像の参照場所を変えたり、ファイル形式を指定したりすることができます。 + +```cpp +#include +#include + +void setup() { + M5.begin(); + M5.Display.drawJpg("/image.jpg", 0, 0); +} + +void loop() { + +} +``` + +### `drawJpg()`の引数の説明 +`drawJpg()`は、本来はM5GFXライブラリのメンバー関数です。しかし、M5Unifiedライブラリを使用すると`Display`または`Lcd`というインスタンスを通じて呼び出すことが可能です。 + +#### 主な引数 +- **`filename`**: 表示したいJPEGファイルのパス。 +- **`x, y`**: 表示開始位置の座標。 +- **`scale` (オプション)**: 表示倍率。 + +例えば、`M5.Display.drawJpg("/image.jpg", 0, 0, 1.0);` とすると、画面の左上から等倍で画像を表示します。 + +## SDカードに保存した画像を表示 +SDカードに保存された画像を表示するには、以下のコードを使用します。 + +```cpp +#include +#include + +void setup() { + M5.begin(); + + if (!M5.Sd.begin()) { + M5.Display.print("SDカードの初期化に失敗しました\n"); + return; + } + + M5.Display.drawJpgFile(SD, "/image.jpg", 0, 0); +} + +void loop() { + +} +``` + +この例では、`drawJpgFile()`関数を使用してSDカードから画像を読み込み、表示します。 + +### `drawJpgFile()`の引数の説明 +- **`fs`**: ファイルシステムオブジェクト(例: SD、SPIFFSなど)。 +- **`filename`**: 読み込むファイル名。 +- **`x, y`**: 表示開始位置の座標。 + +## SPIFFSに保存した画像を表示 +SPIFFSに画像を保存することで、SDカードを使わずに画像を表示できます。 + +```cpp +#include +#include +#include + +void setup() { + M5.begin(); + + if (!SPIFFS.begin()) { + M5.Display.print("SPIFFSの初期化に失敗しました\n"); + return; + } + + M5.Display.drawJpgFile(SPIFFS, "/image.jpg", 0, 0); +} + +void loop() { + +} +``` + +SPIFFSの初期化後、画像ファイルを`drawJpgFile()`で表示します。 + +## URLから画像を表示 +インターネット上の画像を直接取得して表示する場合は、`drawJpgUrl()`を使用します。以下はその例です。 + +```cpp +#include +#include + +const char* ssid = "Your_SSID"; // Wi-FiのSSID +const char* password = "Your_PASSWORD"; // Wi-Fiのパスワード + +void setup() { + M5.begin(); + + // Wi-Fi接続 + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + M5.Display.print("."); + } + M5.Display.println("\nWi-Fi connected"); + + // URLから画像を表示 + const char* url = "https://example.com/image.jpg"; + M5.Display.drawJpgUrl(url, 0, 0); +} + +void loop() { + +} +``` + +### `drawJpgUrl()`の引数の説明 +- **`url`**: 取得するJPEG画像のURL。 +- **`x, y`**: 表示開始位置の座標。 + +## メモリから画像データを表示 +画像データを直接メモリに格納し、表示することも可能です。以下はその例です。 + +```cpp +#include + +const uint8_t imageData[] = { /* 画像データ */ }; + +void setup() { + M5.begin(); + M5.Display.drawJpg(imageData, sizeof(imageData), 0, 0); +} + +void loop() { + +} +``` + +### 画像データを別ファイルに分ける +画像データをプログラム内に直接記述すると、メインコードが見にくくなります。そのため、画像データを別ファイル(例: `image_data.h`)に分けると管理しやすくなります。 + +#### `image_data.h` の例 +```cpp +#ifndef IMAGE_DATA_H +#define IMAGE_DATA_H + +const uint8_t imageData[] = { + // 画像データをここに記述 +}; + +#endif // IMAGE_DATA_H +``` + +メインプログラムでは、このヘッダーファイルをインクルードするだけで画像データを利用できます。 + +### `drawJpg()`の引数(メモリ版) +- **`buf`**: メモリ上の画像データのポインタ。 +- **`len`**: 画像データのサイズ(バイト単位)。 +- **`x, y`**: 表示開始位置の座標。 + +画像データをメモリ上に直接格納するには、画像ファイルをバイナリデータに変換する必要があります。その際、Pythonスクリプトなどを使用して変換を行うと便利です。\ +画像データはメインプログラムに置くと見にくくなってしまうので、 + +## その他の画像形式の対応 +M5Unifiedでは、JPEG以外にも以下の画像形式に対応しています。Jpgの部分を変更することで使用できます。 + +- **PNG** +- **BMP** +- **QOI** + +## ピクセル操作 +画像以外に、ピクセル単位で描画する関数もいくつか利用可能です。 + +- `pushImage()` +- `pushPixels()` +- `pushPixelsDMA()` +- `writePixels()` +- `writePixelsDMA()` + +これらを使用すると、メモリから直接ピクセルデータを送信し、高速に描画できます。 + +## まとめ +M5StackでLCDに画像を表示する方法を解説しました。自分の作りたいものに合わせて選択してください!!