使用 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 中播放动画 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
如何在 android 中从 url 播放动画 GIF 图像?
使用带有 pylab/matplotlib 嵌入的 Tkinter 播放、暂停、停止功能的彩色绘图动画:无法更新图形/画布?