ジェネレータはnext
関数を使って呼び出す。この関数の呼び出し毎にジェネレータは一定の長さのデータを吐き出す。この機構を使って動画ファイルをフレーム毎に読みこむことにする。このような例をimageio
モジュールで見てみる。このモジュールは様々な画像ファイル(動画ファイルを含む)を処理することができる。今回の例は動画ファイルを読み込みヴィデオ表示するPython
プログラムである。
プログラム例
#coding: utf-8
import tkinter as tk, threading
import imageio
from PIL import Image, ImageTk
video_name = "test.mp4" #ここにヴィデオ・ファイル名を書く
video = imageio.get_reader(video_name)
gen = video.iter_data()
def stream(label):
def showlabel():
global count
try:
image=next(gen)
except:
return
frame_image = ImageTk.PhotoImage(Image.fromarray(image))
label.config(image=frame_image)
label.image = frame_image
label.after(14, showlabel) #フレーム・レイトの調整
showlabel()
if __name__ == "__main__":
root = tk.Tk()
root.title('TKinterでヴィデオを見る')
my_label = tk.Label(root)
my_label.pack()
thread = threading.Thread(target=stream, args=(my_label,))
thread.daemon = 1
thread.start()
root.mainloop()
赤い文字の部分がジェネレータに関連する部分で、video = imageio.get_reader(video_name)
はファイルを読み込む機構の設定で、video.iter_data()
でその機構にジェネレータの性格を付与している。
iter_data()
Iterate over all images in the series. (Note: you can also iterate over the reader object.)
と説明がある。
image=next(gen)
でフレーム毎にデータを読み込みそれをimage
に代入している。フレーム毎にデータを読みこみデータが尽きるとエラーになるのでエラー処理をしている。