#はじめに
デジタルフォトフレームは2010年頃に登場した画期的な商品です。
それまで、撮った写真は焼いて飾っても額縁に一枚限りです。その他はアルバム化する必要がありましたし、そもそもよっぽどのことがないと見返すことはありません。
その点デジタルフォトフレームでは、保存した写真が自動でスライドショー化され、ふとした時に何かを思い出す最高のコンテンツといえます。
しかしながらこのフォトフレーム、思いのほか低解像度で低容量、いちいち写真をSDカードに入れたりクラウドにアップロードする面倒な仕組みから、あまり世間に浸透することはありませんでした。
(そもそも現代において写真とは詐欺と欺瞞と加工の事を差し、自己承認ツールの一部になってしまったためにフォトフレームを必要とする時代ではなくなってしまったんですね。)
とはいえこれまで撮ってきた写真、ありのままで見返すと色々思い出がよみがえって面白いですよね。
以上を踏まえると、高解像度で大容量、写真の扱いが面倒でないデジタルフォトフレームがあればQoLが上がるに違いありません。
そこで今回はそんな素晴らしいデジタルフォトフレームを作ろうと思います。
最後までお付き合いいただけると幸いです。
#目標
実のところ、私にとって現在のデジタルフォトフレームがともかく使えないと感じていたのはその容量の無さと写真管理の面倒さでした。
いちいちSDカードに保存とか面倒でたまらないし、管理しなかったらしなかったで永遠に同じ写真のスライドショーは逆に腹が立ちます。
そこで今回はNASサーバーから写真を読み取る仕組みにして、写真アップロードや削除といった管理はすべてパソコンでできるようにして、直接手のかからないような仕組みを目指します。
今回はハードウェアにRaspberry Pi3+を、プログラム言語はPython3を用いました。
#システム
はじめに、ラズパイの設定やメンテナンスも直接手を触れずにやっていきたいのでSSHは有効にしておきましょう。※なお、この際にデフォルトのUN/PWで運用すると警告が邪魔になるので変更推奨です。
つぎに、ラズベリーパイにNASを自動でマウントする設定をしておきましょう。
一定時間たってもモニターが暗くならないようにスリープモードは解除しておきます。
また今回使用したRaspberry Pi3+はPi4用の最新OSを使用すると、仕様の変化から2.4Aの電源では警告が表示されるようになります。構造上は問題ありませんが、目障りなので消しておきましょう。
今後、だれが使っても便利なようにシステムは自動で起動するように登録しておきましょう。(Pythonコードが完成した後)
ちなみにAutoStartを使用した場合に、何故かホームディレクトリ直下のファイルしか起動しないことがあります。上手く起動しなかった人は/home/pi/hogehoge.py
において設定してみると良いかもしれません。
#プログラム
使用したプログラム言語はPython3です。早速、解説していきます。
ほとんどのソースコードは前回の記事、
ここから流用しました。
from PIL import Image, ImageTk
import tkinter
import threading
import random
import time
import os
path = '/mnt/nas/Camera/PhotoFrame/' #NAS上の写真フォルダの場所
使用したライブラリは上記のとおりです。基本的にtkinter
でUI管理、threading
でスライドショーという構造です。
path
はマウントしたNASの画像ファイルの場所を指しています。したがって各々任意に設定してください。
def window():
global canvas, item
root = tkinter.Tk()
root.title()
root.geometry("1920x1080") # ウインドウサイズ指定
root.configure(background='black')
root.attributes("-fullscreen", True) # フルスクリーン化用
canvas = tkinter.Canvas(bg="black", width=1920, height=1080)
canvas.place(x=-1, y=-1)
img = Image.open('image.png') #はじめに表示させる起動画面画像(タイトル的な?)
img = ImageTk.PhotoImage(img)
item = canvas.create_image(0, 0, image=img, anchor=tkinter.NW)
root.mainloop()
こちらは窓(UI)の設定に関する関数です。使用するモニターにあわせて解像度は調整してください。今回は手元のモニターがFull HDだったのでこういう値になっております。
またフルスクリーンは動作確認した後に適応することをお勧めします。さもなくばエラーが生じたときにわかりにくくて不便ですから。
img
はウインドウを設定するのに必要です。プログラムと同一ディレクトリ上に任意の画像を用意してください。ただし映るのは起動後の一瞬だけで、その後は再起動するまでは現れることはありません。適当でいいってことですね。
def repeat():
dir_list = os.listdir(path) #写真の総数をリストへ
i = random.randrange(len(dir_list)) #写真の総数の長さまでの間でランダムな値を生成
img = Image.open(path + dir_list[i]) #ランダムな写真を取得
resize = img.resize((1920, 1080)) #画面サイズに合わせてリサイズ
img_resize = ImageTk.PhotoImage(resize)
canvas.itemconfig(item, image=img_resize)
time.sleep(120) #画像が切り替わる時間
dir_list.clear() #リストをクリア
ここではメインのスライドショーのコードとなるわけですが、このコードではいちいち一枚表示するごとにリストを再生成させて面倒じゃね?とか、randam
に偏りがあったら同じ写真ばっかりでない?とかいろいろ思われるかと思います。
ちなみに全くその通りです。リストは写真の数が多ければ多いほど生成に時間がかかり、写真の切り替えに時間を要するようになります。またランダム関数には一般的に偏りは無いといわれておりますが、見ている限りは相当低い確率の写真の組み合わせが多々生じているので、確かに偏っているように感じます。
しかしながら、こうすることでシステム稼働中の画像の追加や削除が、エラー無く実行することができます。理論上は任意のNASフォルダの中に写真が一枚でもあれば問題ありません。
これはシステムに疎い人が写真アルバムを扱ってもあまり問題が起きないようにしたかったため、です。
ちなみにリサイズ処理はどんな画像もこのサイズになるので、縦長の画像とか比率があってないと中々すごいことになります。ここの処理はもう少しなんとかできるかと思いますが、面倒なので今回はこのまま放置しておきます。大体解像度の高い写真は大丈夫そうですね。
thread = threading.Thread(target=window)
thread.start()
while True:
repeat()
最後にスレッドを立ち上げてスライドショーを繰り返して終了(開始)です。
#まとめ
↑我が家ではこんな感じに運用されています。
思いのほか高解像度であり、またNASの大容量写真フォルダの中からはるか彼方に忘れていた写真が表示されたときなどは、懐かしくもあり話のタネにもなるので大いに役立っています。
今のところ重大な欠陥やエラー等は起きていません。自宅のローカルエリアネットワーク上の使用ではスムーズに事(画像)が運ぶようです。
しかしながら…現代ではスマートフォンのカメラ機能の向上とその便利さ故からか、あまりにも写真を撮りすぎて身に覚えのない写真とか急に表示されます。その間の120秒はホラーです。
NASの画像フォルダの容量以上に、人間の脳みそは低容量のようですね。