You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Tkinter Canvas上显示带透明背景的GIF动画?

解决Tkinter Canvas显示GIF透明背景变白的问题

问题出在GIF的透明机制和PIL的转换方式上:GIF的透明是通过调色板指定透明色实现的,并非原生RGBA通道,直接用convert('RGBA')不会自动将原透明色转为alpha通道,导致透明区域显示为白色。

修改后的代码

import tkinter as tk
from PIL import Image, ImageTk
from itertools import cycle

DELAY = 20

def animate():
    canvas.itemconfig(img, image=next(frames_cycle))
    root.after(DELAY, animate)

root = tk.Tk()
root.geometry('300x300')
root.config(background='red')

frames = []
im = Image.open('loading_circle.gif')
for frame in range(im.n_frames):
    im.seek(frame)
    # 转换为RGBA模式
    frame_img = im.convert("RGBA")
    # 获取GIF的透明色信息
    transparency = im.info.get("transparency")
    if transparency is not None:
        # 从调色板中提取透明色的RGB值
        palette = im.getpalette()
        trans_rgb = tuple(palette[transparency*3 : transparency*3+3])
        # 将图像中所有透明色像素替换为完全透明
        data = frame_img.getdata()
        new_data = []
        for pixel in data:
            if pixel[:3] == trans_rgb:
                new_data.append((255, 255, 255, 0))  # RGBA的alpha设为0(透明)
            else:
                new_data.append(pixel)
        frame_img.putdata(new_data)
    frames.append(ImageTk.PhotoImage(frame_img))

frames_cycle = cycle(frames)

canvas = tk.Canvas(root, bg='red', width=300, height=300)
img = canvas.create_image(120, 0, anchor='nw', image=next(frames_cycle))
canvas.pack()
animate()
root.resizable(False, False)
root.mainloop()

关键说明

  • 先获取GIF帧的transparency(透明色在调色板中的索引),再从调色板中提取对应的RGB值
  • 遍历图像像素,将所有匹配透明色的像素的alpha通道设为0,实现真正的透明效果
  • 保留原图像的非透明像素,确保动画正常显示

内容的提问来源于stack exchange,提问作者Tom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 17:55:47