M5stackでランダムに画像を表示させてみた。 

M5stack core2のディスプレイに複数の画像をランダムに表示させてみました。

## 環境
OS: windows 10.0
M5stack core2 

## 方法
M5stack core2のSDカードに保存している画像の枚数を取得します。そこからランダム関数を使って出てきた値から画像を選択し、一定時間間隔で読み出します。画像の切り替えは、RTCの秒数を使い、一定時間経過後、画像の変更を行うようにします。

## 画像のリサイズ
M5stackのディスプレイは、320✖️240なのでそこに収まるように画像をリサイズします。画像のリサイズには、pythonを用いました。pythonを実行するファイルのディレクトリに加工したい画像データをinputファイル内に入れ、リサイズした結果は、outputに入れるようにしました。

```test.py
from PIL import Image
import os

def resize(img_file):
    img = Image.open(img_file)
    img_x = img.width
    img_y = img.height

    if img_x/200 > img_y/280:
        resize_x = 280
        resize_y = img_y/img_x*280
    else:
        resize_x = img_x/img_y*200
        resize_y = 200    
    
    img_resized = img.resize((int(resize_x), int(resize_y)))
    return img_resized

input_path  =  r"input"
output_path =  r"output"

files = os.listdir(input_path)
file_list = [f for f in files if os.path.isfile(os.path.join(input_path, f))]

if not os.path.exists(output_path):
    os.makedirs(output_path)

for imgfile in file_list:
    resized_img = resize(input_path + '/' + imgfile)
    resized_img.save( output_path + '/' + imgfile, quality=90)
```

## M5stack プログラム
M5stack core2のSDカードに保存している画像は、inputのディレクト下に全て保存しています。input下にある画像ファイルに対し、input下に置かれているファイル数を取得し、```.jpeg```でなければ、枚数から除外するようにしています。
次にランダム関数を使って出てきた値を用いて、画像を選択しています。画像の切り替えは、RTCの秒数を使い、10秒ごとに切り替えるようにしました。```Serial.println```の部分は、値のチェックに使っているだけなので、なくても大丈夫です。

```test.cpp
#include <M5Core2.h>
#include "time.h"

static unsigned char gucOpenFlg = 0;

// for Time
RTC_TimeTypeDef RTC_TimeStruct; // Time
struct tm timeinfo;
String timeStr;

uint16_t img_x = 20;
uint16_t img_y = 20;
const int maxFile = 200;
String fileList[maxFile];
int fileCount = 0;

void setup() {

  M5.begin();

  sdcard_type_t Type = SD.cardType();

  if (Type == CARD_UNKNOWN || Type == CARD_NONE) {
    Serial.printf("SDCard error \r\n");
  } else {
    Serial.printf("SDCard Type = %d \r\n", Type);
    Serial.printf("SDCard Size = %d Mbyte\r\n", (int)(SD.cardSize() / 1024 / 1024));
    Serial.printf("SDCard Use Size = %d Kbyte\r\n", (int)(SD.usedBytes() / 1024));
  }

  File root = SD.open("/output");
  if (root) {
    File file = root.openNextFile();
    while (file) {
      if (file.isDirectory()) {
        // Dir skip
      } else {
        // File
        String filename = file.name();
        Serial.println(filename);
        Serial.println(filename.indexOf(".jpeg"));
        if (filename.indexOf(".jpeg") != -1) {
          // Find
          fileList[fileCount] = filename;
          fileCount++;
          if (maxFile <= fileCount) {
            break;
          }
        }
      }
      file = root.openNextFile();
    }
  }

  Serial.println("File List");
  for (int i = 0; i < fileCount; i++) {
    Serial.println(fileList[i]);
  }

  M5.Lcd.setTextSize(2);
  M5.Lcd.setCursor(60, 80);
  M5.Lcd.printf("Now Loading...");
}

void loop() {

  M5.Rtc.GetTime(&RTC_TimeStruct);
  if(RTC_TimeStruct.Seconds % 10 == 0){
    gucOpenFlg = 0;
    M5.Lcd.clear(BLACK);
  }

  if (0 == gucOpenFlg) {
    int index = random(0, fileCount);
    String filename = fileList[index];
    Serial.printf("Index=%d, File=%s\n", index, filename.c_str());

    M5.Lcd.drawJpgFile(SD, filename.c_str(), img_x, img_y);
    gucOpenFlg = 1;
  }

  delay(1000);
}
```


### デバック
```Serial.println```をArduino IDEのシリアルモニターで出力し、変数の値を確認した。通信速度を115200bpsにしました。それ以外だと文字化けになった。どこかで決まっている値かもしれませんが、調査はしていません。

#### link
参考にしたリンク先です。

[Pythonで画像サイズをリサイズしよう！](https://aiacademy.jp/media/?p=1804)
[M5Stackで画像処理 -静止画の表示から動画作成まで](https://cpp-learning.com/m5stack_image/)
[【M5Stack】第8回 シリアル通信　全集](https://shizenkarasuzon.hatenablog.com/entry/2020/06/23/120550)
[M5Stack Core2 for AWSでSDカードを使って画像表示](https://tomosoft.jp/design/?p=45288)
[JPEG画像の表示](https://m5stack-build.hatenablog.com/entry/2019/10/24/235415)
[【初心者向け】Python os.path.splitext() とは？](https://aiacademy.jp/media/?p=1591)