Pythonでデジタルフォトフレームを作ってみよう!

PRについて
※このサイトはアフィリエイト広告(Amazonアソシエイト含む)を掲載しています。
スポンサーリンク
※このサイトはアフィリエイト広告(Amazonアソシエイト含む)を掲載しています。
Pythonでデジタルフォトフレームを作ってみよう! Tips集
Pythonでデジタルフォトフレームを作ってみよう!
Pythonプログラミング逆引き大全

今回はPythonでデスクトップアプリケーションを作成する際に良く用いられるtkinterを使って、デジタルフォトフレームを作成していこうと思います!

ごまこ
ごまこ

デジタルフォトフレームって簡単に作れるんですか?
ぜひチャレンジしてみたいです!

ごまお
ごまお

実は簡単に作ることができるんです!
Pythonで標準的に呼び出すことができるGUIアプリケーションのライブラリがtkinterなんです!
tkinterの使い方がわからない人にもわかりやすいように詳しく解説していきますね。

はじめに

デジタルフォトフレームとは

デジタルフォトフレームは家族の思い出の写真や風景写真を写真たてのように飾れる家電製品です。

デジタルフォトフレームのイメージ
デジタルフォトフレームのイメージ

こんな家具が自分で作れたら素敵だと思いますよね。

このページでは市販のデジタルフォトフレームのように数秒経つと異なる写真に表示が入れ替わっていくようにしたいと思います。

フレームの入れ替え表示
表示する写真を入れ替えていく

今回使用する画像ファイル

表示に用いる写真はこちらの写真を例に説明していきます。

それでは上記のファイルを保存して早速作っていきましょう!

ごまこ
ごまこ

完成が楽しみになってきました!
いっしょに頑張って取り組んでいきましょう!

プログラムの作成と解説

メイン処理

まずはtkinterを用いて必要なオブジェクトをそろえるためのメイン処理に取り組んでいきます。

詳しく解説していくので、初学者の方も参考にしてください。

プログラム

import tkinter as tk

#--メイン処理--------
app=tk.Tk() #(A)
canvas=tk.Canvas(app,width=500,height=700)
 #(B)
canvas.pack() #(C)

photos = [
tk.PhotoImage(file="cat_a.png"),
tk.PhotoImage(file="cat_b.png"),
tk.PhotoImage(file="cat_c.png")
] #(D)


app.mainloop() #(E)

解説

(A)の部分で、

tkinterのオブジェクトを生成しています。

(B)では、

画像を描画する領域となるCanvasオブジェクトを生成しています。

引数で(A)で作成したtk.Tkオブジェクトを指定し、widthheight高さを指定しています。

(C)で、

生成したCanvasオブジェクトを配置します。

(D)において、

先ほど保存した3枚の画像を読み込みPhotoImageオブジェクトを生成して、リストに3つのPhotoImageオブジェクト代入しています。

後ほど、これらの写真を順番に呼び出す処理を加えていきます。

これらのPhotoImageオブジェクトは(B)(C)で作成・配置した描画領域(キャンバス)にまだ配置されていないので、画像は表示されません

最後に(E)で、

ループ処理を行います。

これにより、表示された画面が閉じられるまで描画が維持され続けます

上のコードを実行すると灰色の画面が表示されます。

描画領域に画像を配置していないので、まだ灰色の画面が表示されるだけです。

生成表示されたウインドウ
実行して表示されたウインドウ

※画面表示されない方はバックグラウンドで表示されています。

 ツールバーに羽マークがあればクリックして画面表示されます。

新規ウインドウがバックグラウンドで起動している
ツールバーの羽マーク

描画処理の関数定義

続いてメイン処理で作成した画面に順番に画像が表示されるように、描画処理を関数として定義します。

以下の関数を5秒ごとに呼び出すことで写真を更新して描画していきます。

プログラム

import tkinter as tk

#--描画処理の関数定義-------
photo_num=0
def photograph():
    global photo_num
    canvas.delete("PH") #(A)
    canvas.create_image(250,350, image=photos[photo_num], tag="PH") #(B)
    photo_num+=1
    
    if photo_num>=len(photos): #(C)
        photo_num=0
    app.after(5000,photograph) #(D)

#--メイン処理--------
#・・・

解説

(A)の部分で、

"PH"というタグのついているオブジェクトを消去します。

画像を繰り返し呼び出して描画していきますが、不要になった写真の消去を行わなければ描画した画像は表示され続けるのでメモリをどんどん圧迫していきます。

そのため、関数を呼び出される度に表示している写真を消去しています。

(B)において、

画像を描画範囲のCanvasオブジェクトに張り付けています。

引数は以下のような意味です。

・250,350で画像の中心を指定
・imageでメイン処理で作成したphotos(PhotoImageの入っているリスト)を指定、このphotograph関数が呼ばれる度にphoto_numを更新していくので順番にPhotoImageオブジェクトの写真が呼び出されます。
・tag="PH"とすることで上記(A)において、不要になった写真が消去されるようにしています。

(C)では、

photos(PhotoImageの入っているリスト)よりもphoto_numが大きくなったらphoto_num=0として初期化しています。

これによって最後の写真が表示された後に、最初の画像が再度表示されるようにしています。

最後に(D)で、

after関数を用いて、5000ミリ秒(=5秒ごとに)ごとに内部からphotograph関数を呼び出します。

こうすることで5秒ごとにphotograph関数が実行されてループし続けるようになります。

完成プログラム

最後にメイン処理部分で、初回のphotograph関数を呼び出すようにします。

完成したプログラムは以下のようになります。

import tkinter as tk

photo_num=0
def photograph():
    global photo_num
    canvas.delete("PH")
    canvas.create_image(250,350, image=photos[photo_num], tag="PH")
    photo_num+=1
    
    if photo_num>=len(photos):
        photo_num=0
    app.after(5000,photograph)

app=tk.Tk()
canvas=tk.Canvas(app,width=500,height=700)
canvas.pack()

photos = [
tk.PhotoImage(file="cat_a.png"),
tk.PhotoImage(file="cat_b.png"),
tk.PhotoImage(file="cat_c.png")
]

#初回のphotograph関数を呼び出し。
#二回目以降は7秒ごとに関数内部からphotograph関数が呼び出される。
photograph()
app.mainloop()

実行すると以下のように、5秒ごとに写真が更新されて表示されます!

ごまこ
ごまこ

デジタルフォトフレームができました!
tkinterを使ったプログラムは独特なので難しかったです。

ごまお
ごまお

実は僕もtkinterを使えるようになるのに時間がかかりました!
こんな風に楽しく何かを作りながら勉強するのがオススメです!

まとめ

デジタルフォトフレームは完成しましたでしょうか。

tkinterの使い方に慣れていない方は書き方にとまどったかもしれませんね。

今回のプログラムを使わないタブレットやRaspberry Piで実行すれば、立派なデジタルフォトフレームとして自宅で使うこともできると感じます。

また、今回プログラムは改善していく余地はまだまだたくさんあると思います。

画像の大きさに合わせて描画範囲を調整したり、画像データ名を指定しなくてもフォルダ内の写真を自動で取得できるようにしたらより便利に使うことができるでしょう。

興味のある方は自分なりの改善にチャレンジしてみてください!

このサイトの記事一覧へは以下へアクセス!

Python自動処理の教科書
Tips集
ゴマフリーダムをフォローする

コメント

達人に学ぶDB設計 徹底指南書

最短コースでわかる ディープラーニングの数学

あたらしい機械学習の教科書 第3版

ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装

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