Raspberry Pi PicoでAT-Xを作る⑦-1 LCD(Pico-LCD-1.14)にバイナリ形式の画像を表示する

raspberry pi pico
oplus_32

今回は画像ファイルをバイナリデータに変換して表示した。

余談:困ったこと

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に表示する

表示させる画像は↓これ

image1

画像をバイナリデータに変換

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で表示できるのか試してみる

タイトルとURLをコピーしました