Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/content/blog-metas/2024-12-23-m5stack.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"postDate": "2024-12-26T11:27:15.913Z"
}
199 changes: 199 additions & 0 deletions src/content/blogs/2024-12-23-m5stack.md
Original file line number Diff line number Diff line change
@@ -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 <Arduino.h>
#include <M5Unified.h>

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 <Arduino.h>
#include <M5Unified.h>

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 <Arduino.h>
#include <M5Unified.h>
#include <SPIFFS.h>

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 <M5Unified.h>
#include <WiFi.h>

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 <M5Unified.h>

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に画像を表示する方法を解説しました。自分の作りたいものに合わせて選択してください!!