質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

7016閲覧

Python(TkInter) 動作があるGIFアニメーションを表示したいですが 現在 停止画像として表示されてしまっています。

saya24

総合スコア221

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/06/17 08:55

編集2020/06/17 08:56

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ページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答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
teamikl

総合スコア8664

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

saya24

2020/06/17 23:30

teamiklさん、ご丁寧な解説をありがとうございます。Pythonを始めたばかりの自分には難易度が高い話だったのですね~、すみません。 一先ず、簡易版から今試してみますね。まずはお礼まで
saya24

2020/06/18 00:09

今しがたご紹介の簡易版まるっと貼り付け試しましたが十分じゃないですか~、大満足、感動しております!!! 丁寧にPILを利用したバージョンをご紹介頂いており非常に申し訳ないのですが、今回ひとまず簡易版で進めようと思います。 ご紹介頂きましたラベルに文字がスクロールされて表示されるサンプルは 大変魅力的ですね~。将来参考になるかも知れません。 現在開発中のものにうまく適用ができたら 当案件クローズさせて頂きます。(簡易版を適用する上で不明点が生じたら 引き続きご見解を仰ぐ可能性もございますので)
saya24

2020/06/18 02:44

動作するGIFアニメーションの適用、無事にできました。 ありがとうございました。 贅沢にも Yes・Noの確認ダイアログを表示させ、その回答次第でGIFアニメーションを切替えることを達成しようとする課題にチャレンジしておりますが、今度は その課題に躓いております。 別の案件として 掲載させて頂きますが 差し支えなければ 引き続きご確認頂けたら幸いです 一連 ありがとうございました。
teamikl

2020/06/18 05:14

他のGUIライブラリだと簡単だけど、tkinterでは~という事例ですね。 実写系のアニメーションはうまくいかない、 (いわゆるベタ塗りな)アニメ絵は比較的対応できる感じでした。 自分の試した限りでは、適当に検索して集めたGIFファイルだった為か、 うまく表示できない事のほうが多かったのですが、 最悪、簡易版でも、最適化なしのGIFファイルを作成することで、 そういった形式のファイルにも対応できそうです。(画像のファイルサイズは大きくなります)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問