使用 Tkinter 在 GIF 中播放动画 [重复]

Posted

技术标签:

【中文标题】使用 Tkinter 在 GIF 中播放动画 [重复]【英文标题】:Play Animations in GIF with Tkinter [duplicate] 【发布时间】:2021-12-02 17:23:43 【问题描述】:

我一直在尝试使用Tkinter.PhotoImage 播放动画 gif,但没有看到任何成功。它显示图像,但不显示动画。以下是我的代码:

root = Tkinter.Tk()
photo = Tkinter.PhotoImage(file = "path/to/image.gif")
label = Tkinter.Label(image = photo)
label.pack()
root.mainloop()

它在窗口中显示图像,仅此而已。我认为这个问题与Tkinter.Label 有关,但我不确定。我一直在寻找解决方案,但他们都告诉我使用 PIL(Python Imaging Library),这是我不想使用的东西。

有了答案,我又创建了一些代码(还是不行...),这里是:

from Tkinter import *

def run_animation():
    while True:
        try:
            global photo
            global frame
            global label
            photo = PhotoImage(
                file = photo_path,
                format = "gif - ".format(frame)
                )

            label.configure(image = nextframe)

            frame = frame + 1

        except Exception:
            frame = 1
            break

root = Tk()
photo_path = "/users/zinedine/downloads/091.gif"

photo = PhotoImage(
    file = photo_path,
    )
label = Label(
    image = photo
    )
animate = Button(
    root,
    text = "animate",
    command = run_animation
    )

label.pack()
animate.pack()

root.mainloop()

感谢一切! :)

【问题讨论】:

您可以通过在 Canvas 小部件 (C.create_image(x, y, image=photo) 上使用它来检查它是否与附加到 Label 小部件有关。 我不知道我是否对Canvas 做错了,但我只看到图像的右下角,而且看起来像素化了... 尝试先使用非动画图像,然后再切换到动画图像。 非动画 gif 也会发生同样的事情... 没有看到代码我只能说你一定做错了。 【参考方案1】:

您必须自己在 Tk 中驱动动画。动画 gif 由单个文件中的多个帧组成。 Tk 加载第一帧,但您可以在创建图像时通过传递索引参数来指定不同的帧。例如:

frame2 = PhotoImage(file=imagefilename, format="gif -index 2")

如果您将所有帧加载到单独的 PhotoImages 中,然后使用计时器事件来切换正在显示的帧 (label.configure(image=nextframe))。计时器上的延迟可让您控制动画速度。除了超出帧数后无法创建帧外,没有提供任何内容来为您提供图像中的帧数。

请参阅photoTk 手册页了解官方用语。

【讨论】:

听起来像 tKludge。 我还应该问是否有办法确定图像的帧数;试过这个:***.com/questions/7503567/… 另外,对于 2500 张图像,有没有办法让它自动完成? 请参阅en.wikipedia.org/wiki/GIF#Animated_GIF 了解布局。 GIF 文件不包含许多帧 - 只有每帧的延迟可能是可变的。 您能否为此提供一个可验证的示例?【参考方案2】:

这是一个不创建对象的简单示例:

from tkinter import *
import time
import os
root = Tk()

frameCnt = 12
frames = [PhotoImage(file='mygif.gif',format = 'gif -index %i' %(i)) for i in range(frameCnt)]

def update(ind):

    frame = frames[ind]
    ind += 1
    if ind == frameCnt:
        ind = 0
    label.configure(image=frame)
    root.after(100, update, ind)
label = Label(root)
label.pack()
root.after(0, update, 0)
root.mainloop()

【讨论】:

您能否解释一下您的代码,以便其他人可以从中学习,而不是复制粘贴一些可能有效也可能无效的代码? 看起来它可以工作,但它踢出了一个列表索引超出了 frame = frames[ind] 的范围 @Apostolos:这是因为您尝试加载 100 帧,但您使用的 gif 少于 100 帧。尝试将 100 帧减少到 10 帧,然后逐渐增加,直到遇到错误。 我明白了。这显然是事实。所以,这次我用了一个 32 帧的 GIF 文件,将 100 替换为 32。当动画中显示所有帧时,我仍然得到“IndexError: list index out of range”。无论如何,我已经创建了自己的程序,也计算帧数......而且,它也很流畅......在上面的例子中,帧大小发生了变化,效果很糟糕。我希望你已经解决了这个问题。 一种非常有趣的方式,虽然它只适用于正好 100 帧的 GIF。

以上是关于使用 Tkinter 在 GIF 中播放动画 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

能够播放gif动画的ImageView

如何在 android 中从 url 播放动画 GIF 图像?

python-tkinter如何打开动图(.gif)?

Java GIF 动画未正确重绘

Android加载Gif动画

使用带有 pylab/matplotlib 嵌入的 Tkinter 播放、暂停、停止功能的彩色绘图动画:无法更新图形/画布?