今回は画像ファイルをバイナリデータに変換して表示した。
余談:困ったこと
microSD内のフォルダが認識されない
vscode上にsdカード内のディレクトリが表示されなくて、
ファイルの授受をわざわざThonnyでやってたんだけど、あまりに面倒だったから
main.pyを作って対応した。
import machine
import os
import sdcard
sd = sdcard.SDCard(machine.SPI(0), machine.Pin(28))
vfs = os.VfsFat(sd)
os.mount(vfs, '/sd')
これをmain.pyって名前でラズパイピコに入れた。
ラズパイピコをPCに繋いだらまずmicroSDをマウントしてくれるようになった。
画像を表示してみる
手順としては、
①PCであらかじめ画像をバイナリデータに変換
②ラズパイピコにコピー
③バッファに持たせてLCDに表示する
表示させる画像は↓これ

画像をバイナリデータに変換
from PIL import Image
import struct
img = Image.open("image1.png").convert("RGB").resize((240, 135))
with open("image1.bin", "wb") as f:
for y in range(img.height):
for x in range(img.width):
r, g, b = img.getpixel((x, y))
rgb565 = ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3)
f.write(struct.pack(">H", rgb565))
変換したい画像ファイルがimage1.png
出力するbinファイル名をimage1.bin
表示してみる
image.binをラズパイピコのディレクトリ直下に配置して
↓のソースを実行した
import tft_config
# LCD 初期化
tft = tft_config.config()
print('画像を表示します')
with open('image1.bin', "rb") as f:
buf = f.read()
tft.blit_buffer(buf, 0, 0, 240, 135)
print('完了')
よくわからんジャギジャギが表示された

画面の向きの設定が間違ってたっぽい。
tft_config.pyのconfig()の引数rotation=0をrotation=1に修正した。

上手く表示された

2枚の画像を連続で表示してみる
2枚目に表示する画像はこれ。どアップの豚山。

単純なソースを書いたら
2枚目の画像をバッファにセットした行でメモリ不足のエラーが出た。
import tft_config
import time
# LCD 初期化
tft = tft_config.config()
print('画像を表示します')
with open('image1.bin', "rb") as f:
buf = f.read()
tft.blit_buffer(buf, 0, 0, 240, 135)
time.sleep(2)
with open('image2.bin', "rb") as f:
buf = f.read()
tft.blit_buffer(buf, 0, 0, 240, 135)
print('完了')
MemoryError: memory allocation failed, allocating 50432 bytes
with文で書いてるから問題ないと思ったけど
変数bufを解放してなかった。
del bufを追加した修正後
import tft_config
import time
# LCD 初期化
tft = tft_config.config()
print('画像を表示します')
with open('image1.bin', "rb") as f:
buf = f.read()
tft.blit_buffer(buf, 0, 0, 240, 135)
time.sleep(2)
del buf
with open('image2.bin', "rb") as f:
buf = f.read()
tft.blit_buffer(buf, 0, 0, 240, 135)
print('完了')
結果
何fpsで表示されるのか計測してみる
2枚を連続で切り替えて1秒に何枚の画像を表示できるのか計測してみる
import tft_config
# LCD 初期化
tft = tft_config.config()
print('画像を連続表示します')
for i in range(30):
with open('image1.bin', "rb") as f:
buf = f.read()
tft.blit_buffer(buf, 0, 0, 240, 135)
del buf
with open('image2.bin', "rb") as f:
buf = f.read()
tft.blit_buffer(buf, 0, 0, 240, 135)
del buf
print('完了')
実行中の様子
おせ~。
ラズパイピコと二郎系ラーメンが高速で切り替わる謎の動画、面白くない?
画面表示開始のフレームから30フレーム(0.98秒)を切り抜いた。
※再生ボタン押すと、詰まったフレームは飛んじゃうっぽいから
シークバーを右にゆっくり動かして確認してみて
7fps。思ったより悪くないかもとか思った。
おわりに
次回はドライバのbitmapメソッドを使って
画像を表示するのと、交互に画像を切り替えて何fpsで表示できるのか試してみる