python - 使用 Tkinter 的动画 gif 没有透明度

标签 python tkinter transparency animated-gif

我想用 Tkinter 显示动画 gif。我尝试使用建议的解决方案 here .

问题是在我的 gif 中,只有第一帧是完整的。所有其他帧都包含一个大部分透明的区域,其中只有少数像素会改变 w.r.t.前一帧是不透明的。

我能告诉 Tkinter 这些框架的背景应该是透明的吗?

from Tkinter import * 
from PIL import Image, ImageTk


class MyLabel(Label):
    def __init__(self, master, filename):
        im = Image.open(filename)
        seq =  []
        try:
            while 1:
                seq.append(im.copy())
                im.seek(len(seq)) # skip to next frame
        except EOFError:
            pass # we're done

        try:
            self.delay = im.info['duration']
        except KeyError:
            self.delay = 100

        first = seq[0].convert('RGBA')
        self.frames = [ImageTk.PhotoImage(first)]

        Label.__init__(self, master, image=self.frames[0])

        temp = seq[0]
        for image in seq[1:]:
            temp.paste(image)
            frame = temp.convert('RGBA')
            self.frames.append(ImageTk.PhotoImage(frame))

        self.idx = 0

        self.cancel = self.after(self.delay, self.play)

    def play(self):
        self.config(image=self.frames[self.idx])
        self.idx += 1
        if self.idx == len(self.frames):
            self.idx = 0
        self.cancel = self.after(self.delay, self.play)        


root = Tk()
anim = MyLabel(root, 'animated.gif')
anim.pack()

def stop_it():
    anim.after_cancel(anim.cancel)

Button(root, text='stop', command=stop_it).pack()

root.mainloop()

最佳答案

看起来您需要为粘贴操作提供掩码:

from Tkinter import * 
from PIL import Image, ImageTk


class MyLabel(Label):
    def __init__(self, master, filename):
        im = Image.open(filename)
        seq =  []
        try:
            while 1:
                seq.append(im.copy())
                im.seek(len(seq)) # skip to next frame
        except EOFError:
            pass # we're done

        try:
            self.delay = im.info['duration']
        except KeyError:
            self.delay = 100

        first = seq[0].convert('RGBA')
        self.frames = [ImageTk.PhotoImage(first)]

        Label.__init__(self, master, image=self.frames[0])

        lut = [1] * 256
        lut[im.info["transparency"]] = 0

        temp = seq[0]
        for image in seq[1:]:
            mask = image.point(lut, "1")
            # point() is used to map image pixels into mask pixels
            # via the lookup table (lut), creating a mask
            # with value 0 at transparent pixels and
            # 1 elsewhere
            temp.paste(image, None, mask) #paste with mask
            frame = temp.convert('RGBA')
            self.frames.append(ImageTk.PhotoImage(frame))

        self.idx = 0

        self.cancel = self.after(1000, self.play)

    def play(self):
        self.config(image=self.frames[self.idx])
        self.idx += 1
        if self.idx == len(self.frames):
            self.idx = 0
        self.cancel = self.after(self.delay, self.play)        


root = Tk()
anim = MyLabel(root, 'tumblr_m3i10ma4fI1qe0eclo1_r9_500.gif')
anim.pack()

def stop_it():
    anim.after_cancel(anim.cancel)

Button(root, text='stop', command=stop_it).pack()

root.mainloop()

关于python - 使用 Tkinter 的动画 gif 没有透明度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20370864/

相关文章:

python - 为什么 tkinter 键事件 <Tab> 的优先级高于 tkinter 键事件 <key>?

python - 尝试修复tkinter GUI卡住(使用线程)

C# 在 50% 不透明窗体上绘制的透明实心矩形

python - PyOpenGL 如何导入 obj 文件?

Python 继承输出

python - 如果某一列相同,则将一行中的空值与其他行归入空值

python - BytesIO 对象到图像

python - 在 x 轴上绘制音频时间而不是 matplotlib 图形的 tkinter GUI 显示中的音频采样率

css - 实现背景过滤器 : opacity(0%) in CSS

html - 来自不透明图像的半透明背景