こんにちは!今回は、Raspberry Piを使ったデジタルサイネージの作り方をご紹介します。Pythonで「2枚の画像をランダムに横並びで1秒ごとに切り替える」とfehでの「シンプルなサイネージ」の構築方法を紹介しています。
お店の装飾や展示ブースにぴったりの仕組みをPythonで簡単に作ってみましょう。
実現したい機能
- Raspberry Piで動作
- 画面を左右に2分割し、画像を同時に2枚表示 (Python)
- フォルダ内の大量画像からランダムに選出
- 1秒ごとに画像を切り替え
- 表示ディスプレイのサイズに自動対応
- キーボード操作で安全に停止 (Python)
使用したもの
環境
- OS: Raspberry Pi OS(Lite/FullどちらでもOK)
- Python 3(デフォルトで搭載)
- ライブラリ:
Pillow
, screeninfo
インストールしていない場合は、以下でインストールできます:
pip install pillow screeninfo
フォルダ構成(共通)
/home/pi/signage/
├── images/
│ ├── img1.jpg
│ ├── img2.png
│ └── ...
├── signage.py # Python用スクリプト
└── show_feh.sh # feh用シェルスクリプト
方法①:Python( Pillow + screeninfo)で柔軟に作る
Pythonコード(signage.py)
import tkinter as tk
from PIL import Image, ImageTk
import os
import random
from screeninfo import get_monitors
# === 設定 ===
IMAGE_FOLDER = "./images"
UPDATE_INTERVAL = 1000 # ms
# === モニターサイズ取得 ===
monitor = get_monitors()[0]
SCREEN_WIDTH = monitor.width
SCREEN_HEIGHT = monitor.height
# === 対象画像ファイル取得 ===
def load_images(folder):
extensions = ('.jpg', '.jpeg', '.png', '.bmp', '.gif')
return [os.path.join(folder, f) for f in os.listdir(folder) if f.lower().endswith(extensions)]
images = load_images(IMAGE_FOLDER)
if len(images) < 2:
raise Exception("画像が2枚以上必要です")
# === GUI初期化 ===
root = tk.Tk()
root.attributes('-fullscreen', True)
root.configure(bg='black')
canvas_left = tk.Canvas(root, bg='black', highlightthickness=0)
canvas_right = tk.Canvas(root, bg='black', highlightthickness=0)
canvas_left.place(x=0, y=0, width=SCREEN_WIDTH//2, height=SCREEN_HEIGHT)
canvas_right.place(x=SCREEN_WIDTH//2, y=0, width=SCREEN_WIDTH//2, height=SCREEN_HEIGHT)
canvas_images = [None, None] # ImageTk.PhotoImageの保持用
# === リサイズ保持で表示位置調整 ===
def fit_and_center(img, max_width, max_height):
img_width, img_height = img.size
ratio = min(max_width / img_width, max_height / img_height)
new_size = (int(img_width * ratio), int(img_height * ratio))
resized = img.resize(new_size, Image.LANCZOS)
return resized, new_size
# === 画像更新関数 ===
def update_images():
selected = random.sample(images, 2)
canvases = [canvas_left, canvas_right]
for i in range(2):
img = Image.open(selected[i])
canvas = canvases[i]
canvas.delete("all")
resized_img, new_size = fit_and_center(img, SCREEN_WIDTH // 2, SCREEN_HEIGHT)
canvas_images[i] = ImageTk.PhotoImage(resized_img)
x = (SCREEN_WIDTH // 2 - new_size[0]) // 2
y = (SCREEN_HEIGHT - new_size[1]) // 2
canvas.create_image(x, y, image=canvas_images[i], anchor='nw')
root.after(UPDATE_INTERVAL, update_images)
# === キーボードで終了 ===
def on_key(event):
if event.keysym in ('Escape', 'q', 'Q'):
root.destroy()
root.bind("<Key>", on_key)
# === 実行 ===
update_images()
root.mainloop()
停止方法
キー | 動作 |
---|---|
q または Q | アプリを終了 |
Esc | アプリを終了 |
注意点とカスタマイズ
- 画像サイズは大きすぎても自動調整されますが、横長画像の方がきれいに収まります。
- 表示間隔を変えたい場合は
UPDATE_INTERVAL
の値を変更してください。 - ディスプレイが縦型の場合は
screen_width
とscreen_height
を調整すればOK。
方法②:fehで手軽にランダムスライドショー表示
「とにかく軽くて速く、少ないリソースで動かしたい」場合は、画像ビューア feh
を使う方法が便利です。
fehのインストール
sudo apt update
sudo apt install feh -y
スライドショー用スクリプト作成
以下のスクリプトを /home/pi/slideshow.sh
に保存します。
#!/bin/bash
# 表示対象ディレクトリ
IMG_DIR="/home/pi/signage/images"
# スライドショーの設定:全画面、1秒間隔、自動ループ
feh --fullscreen --slideshow-delay 1 --hide-pointer --auto-zoom "$IMG_DIR"
動作確認
/home/pi/slideshow.sh
このコマンドでスライドショーが全画面で開始されれば成功です。
停止方法
方法①:キーボード操作で終了
feh
でスライドショー中に、キーボードの以下のキーを押すことで停止できます:
q
:終了(quit)Esc
:終了Ctrl + C
:ターミナルから起動している場合は終了
方法②:バックグラウンドで起動している場合に停止
もし feh
を 自動起動設定(autostart)やスクリプトでバックグラウンド起動している場合、ターミナルで以下のコマンドを実行して停止できます:
pkill feh
これにより feh
プロセスを強制終了します。
方法③:GUIから停止(デスクトップ環境)
- 画面がスライドショーで塞がれている場合、
Ctrl + Alt + F1
~F6
を押して仮想ターミナルに切り替え →pkill feh
- またはマウスカーソルを表示させた状態で
Alt + Tab
などで別のウィンドウに切り替え
fehの特徴
機能 | Python版 | feh |
---|---|---|
ランダム表示 | ✅ | ✅ |
画面サイズに応じてリサイズ | ✅ | ✅(--auto-zoom ) |
ESCキーで終了 | ✅ | ✅ |
複雑な制御(左右別表示など) | ✅ | ❌ |
表示速度・軽さ | △ | ◎ |
使い分けのポイント
- Python:左右2分割や画像制御、UI連携など柔軟な設計が可能。少しコードを書く必要あり。
- feh:シンプルな全画面スライドショーには最適。最小限の労力で導入可能。
注意点
- Raspberry PiでのGPUメモリ割当を
raspi-config
で64MB以上にしておくと安定します - HDMIディスプレイが正しく検出されていないと全画面表示がうまくいかない場合があります
まとめ
Raspberry Piを使えば、手軽に本格的なデジタルサイネージが作れます!
店舗やイベントでの活用はもちろん、自宅でのフォトフレーム代わりにも便利です。
ご不明な点や「もっとこうしたい!」という要望があれば、お気軽にお問い合わせください!