Pygame で写真のスライドショーを作る on Raspberry Pi

Raspberry Pi 用にモニター (ELECROW 7インチ モニター 1024x600) を買ってみたので、写真のスライドショーでもと考え方法を調べてみたところ Pygame を使うと非常に簡単に書けることがわかりました。その方法のご紹介です。

まず Raspbery Pi 上で python3 と pygame が入っているかを確認します。以下のコマンドを叩いてエラーが出なければ O.K.。Raspbian Stretch (November 2018) はデフォルトの状態でインストールされていました。

<pre>
$ python3
Python 3.5.3 (default, Sep 27 2018, 17:25:39)
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pygame
>>>
</pre>

スクリプトと同じディレクトリに imgs ディレクトリを作り表示したい JPEG ファイルを転送します。さらに実際に表示用ファイルを作成するための small ディレクトリをその下に作成します

<pre>
~/Python $ mkdir imgs
~/Python/imgs $ cd imgs
ファイルをこのディレクトリに転送
~/Python/imgs $ ls *.jpg | head -3
WP_000008.jpg
WP_000009.jpg
WP_000029.jpg
~/Python/imgs $ mkdir small
</pre>

ファイル変換用に imagemagick をインストール。convert コマンドで表示用のファイルを作成します。1024x600 は自分の持っているモニタの解像度に合わせます。

<pre>
~/Python/imgs $ sudo apt-get -y install imagemagick
~/Python/imgs $ for i in `ls *.jpg`; do echo "convert -quality 100 -resize 1024x600 ${i} ./small/${i%.*}_s.jpg" ; convert -quality 100 -resize 1024x600 ${i} ./small/${i%.*}_s.jpg; done
~/Python/imgs $ ls ./small/*.jpg | head -3
./small/WP_000008_s.jpg
./small/WP_000009_s.jpg
./small/WP_000029_s.jpg
</pre>

一回親ディレクトリに戻って、こんな感じのスクリプトを書きます。interval で次の写真が表示されるまでの秒数を指定します。

<pre>
~/Python/imgs $ cd ..
~/Python $ vi slide_show.py
ファイルを編集
$ cat ./slide_show.py
#!/usr/bin/env python3
import sys
import pygame
from os import listdir
from pygame.locals import QUIT, KEYDOWN, K_ESCAPE

pygame.init()
SURFACE = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
FPSCLOCK = pygame.time.Clock()

path = "/home/pi/Python/imgs/small/"
list = listdir(path)
list_len = len(list) - 1
interval = 4

def main():
    pic_num = 0
    counter = 0
    x_center = SURFACE.get_width()/2
    y_center = SURFACE.get_height()/2
    pygame.mouse.set_visible(False)

    while True:
        for event in pygame.event.get():
            if event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    pygame.quit()
                    sys.exit()

        SURFACE.fill((0,0,0))

        pic = pygame.image.load(path+list[pic_num])
        rect = pic.get_rect()
        rect.center = (x_center,y_center)
        SURFACE.blit(pic,rect)

        counter += 1
        if((counter % interval) == 0):
            if(pic_num >= list_len):
                pic_num = 0
            else:
                pic_num += 1

        pygame.display.update()
        FPSCLOCK.tick(1)

if __name__ == '__main__':
    main()
</pre>

次に slide_show.py を実行。フルスクリーンで写真が表示されます。DISPLAY 変数を設定していれば ssh でログインしているターミナルからも実行できます。終了は Raspberry Pi に取り付けてあるキーボードの ESC キーを押します。ssh でログインしている場合はもちろん Ctrl-C で終了します。

<pre>
$ echo $DISPLAY
:0.0
$ ./slide_show.py
</pre>

Raspberry Pi が起動した後に自動的に実行したい場合は ~/.config/autostart/slide_show.desktop に以下のように記述。

<pre>
~ $ mkdir ~/.config/autostart/
~ $ vi .config/autostart/slide_show.desktop
ファイルを編集
~ $ cat .config/autostart/slide_show.desktop
[Desktop Entry]
Exec=lxterminal -e "/home/pi/Python/slide_show.py"
Type=Application
~ $ sudo reboot
</pre>

Raspberry Pi を再起動すると自動的にターミナルが立ち上がりその後フルスクリーンで写真が表示されるようになります。全画面占領してしまうので ssh で入れるか、キーボードの ESC でプログラムが終了させられるかを事前に確認しておくことをおすすめします。