Python
1self.lbimage = PhotoImage(file='images\taiko-bs.gif') 2lb1 =Label(self,image=self.lbimage, relief="sunken", borderwidth=3) 3lb1.pack(fill = BOTH, expand=True)
ラベルに採用していることがマズいのでしょうか?
それとも PhotoImage関数?!を利用していることがまずのでしょうか?
【質問】
IEで確認すると動作しているGIFアニメーションを TkInterのGUIフォーム上でも 動作させる採用方法を教えてください。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答1件
0
ベストアンサー
残念ながらアニメーションGIFの再生はサポートされてません。
タイマー(afterメソッド)を使い描画を更新する処理を実装する必要があります。
PhotoImage でフレームの読込はサポートされているので、
順番に更新してアニメーションのようにすることはできますが、
幾つか課題はあって
- 画像の背景色次第では、透過のような色抜けが発生する。
- アニメーション速度が所得出来ない。これは gif ファイルを読み込んで解析する必要があります。
- フレームの再利用等に対応できない。同上です。
より詳細に対応しようとすると、画像処理ライブラリのPIL(Pillow)を使い
アニメーション処理を自分で実装することになります。
色々と制限があるので、拘りがなければ
素直に tkinter 以外の GUI ライブラリを検討しても良いと思います。
PILを使わない簡易版: PhotoImage のオプションでGIFのフレーム読出
python
1import tkinter as tk 2 3root = tk.Tk() 4photo = tkinter.PhotoImage(file="test.gif") 5gif_index = 0 6 7def next_frame(): 8 global gif_index 9 try: 10 # XXX: 次のフレームに移る 11 photo.configure(format="gif -index {}".format(gif_index)) 12 13 gif_index += 1 14 except tkinter.TclError: 15 gif_index = 0 16 return next_frame() 17 else: 18 root.after(100, next_frame) # XXX: アニメーション速度が固定 19 20label = tkinter.Label(root, image=photo) 21label.pack() 22 23root.after_idle(next_frame) 24root.mainloop()
問題点は:
- アニメーション速度が一定
- 色数の少なく、毎フレーム画像全体が書き換わるものしか扱えない (フレームが差分のみはx)
→ 最適化されているような形式のファイルは扱えません。
妥協案とするなら、
色数が少なく、アニメーション速度が一定で、毎フレーム画像全体が書き換わるような形式
のGIFなら、これで対応できます。(そのような形式のGIFファイルを準備すれば)
- 同アプローチなので同じ問題点を持ちますが、使いやすくクラスにまとめられた実装。
AnimatedGIF
ここからは、敢えて tkinter で実装する場合
参考:
https://stackoverflow.com/questions/7960600/python-tkinter-display-animated-gif-using-pil
PILを使い im.info['duration']
を参照しているコードを参考にします。
2.7用のコードのようですが、import の Tkinter
-> tkinter
のみの変更で動きます。
但し、これも速度が一定なので途中で速度が変化するようなアニメーションには対応していません。
以下はその速度変化の対応パッチ。(あまり十分なテストはしてません)
diff
1--- test_pil_label.orig.py 2020-06-18 01:35:20.326016300 +0900 2+++ test_pil_label.py 2020-06-18 01:38:28.341683900 +0900 3@@ -1,25 +1,23 @@ 4-from Tkinter import * 5+from tkinter import * 6 from PIL import Image, ImageTk 7 8 9 class MyLabel(Label): 10 def __init__(self, master, filename): 11 im = Image.open(filename) 12- seq = [] 13+ seq = [] 14+ delays = [] 15 try: 16 while 1: 17 seq.append(im.copy()) 18+ delays.append(im.info["duration"]) 19 im.seek(len(seq)) # skip to next frame 20 except EOFError: 21 pass # we're done 22 23- try: 24- self.delay = im.info['duration'] 25- except KeyError: 26- self.delay = 100 27- 28 first = seq[0].convert('RGBA') 29 self.frames = [ImageTk.PhotoImage(first)] 30+ self.delays = delays 31 32 Label.__init__(self, master, image=self.frames[0]) 33 34@@ -31,14 +29,16 @@ 35 36 self.idx = 0 37 38- self.cancel = self.after(self.delay, self.play) 39+ self.cancel = self.after(self.delays[0], self.play) 40 41 def play(self): 42- self.config(image=self.frames[self.idx]) 43+ image = self.frames[self.idx] 44+ delay = self.delays[self.idx] 45+ self.config(image=image) 46 self.idx += 1 47 if self.idx == len(self.frames): 48 self.idx = 0 49- self.cancel = self.after(self.delay, self.play) 50+ self.cancel = self.after(delay, self.play) 51 52 53 root = Tk()
追記: コードはtcl ですが、Pythonの配布物の中にtcl/tkのサンプルコードが有り
ラベルに animation gif を表示するデモがあります。実装は上の PIL を使わない方と同じ。
投稿2020/06/17 17:25
編集2020/06/17 17:43総合スコア8760
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/06/17 23:30
2020/06/18 00:09
2020/06/18 02:44
2020/06/18 05:14