Tkinter screwing with PIL image transparency?

Viewed 86

I made a custom image viewing program in python since I couldn't find one that worked how I wanted it to, and I know it at least USED to work with transparent gifs but now it doesn't. The effects seem to vary from gif to gif to gif but it always is an issue with the transparency. Doing some testing with .save I found that the PIL image is completely fine and I can export it as a png with absolutely no issues and perfect transparency. With that said, despite making the program I never really learned Tkinter since I just didn't need to use it beyond simple canvas clearing and updating, so I have no clue how to test beyond PIL. I believe the issue should be in these lines :

image = ImageTk.PhotoImage(GifFrameSized) #GifFrameSized is the resized GIF
imagesprite = canvas.create_image(show.w/2,show.h/2,image=image) #w and h are the width and height of the monitor
root.update_idletasks()
root.update()
canvas.pack()

I genuinely have no idea how the issue could be coming from any of these but I was able to use PIL to save a png of the frame in the line immediately above "image = ImageTk.PhotoImage(GifFrameSized)" and it looked fine so I have to imagine its somewhere in those lines.

1 Answers

So I used this gif file and it works as expected. There seems no magic in achieving it. I just get a image reference to each frame of the animated image and make a itertools.cycle out of it with:

frames = []
im = Image.open('52O8.gif')
for frame in range(im.n_frames):
    im.seek(frame)
    frames.append(ImageTk.PhotoImage(im.copy()))
frames_cycle=cycle(frames)

and later I just iterate every 100ms over the cycle to show a different frame in my canvas with:

DELAY = 100

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

Full Code

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

DELAY = 100

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

root = tk.Tk()
root.config(background='black')

frames = []
im = Image.open('52O8.gif')
for frame in range(im.n_frames):
    im.seek(frame)
    frames.append(ImageTk.PhotoImage(im.copy()))
frames_cycle=cycle(frames)

canvas = tk.Canvas(root,bg='black',width=400,height=400)
img = canvas.create_image(0,0,anchor=tk.NW,image=next(frames_cycle))
canvas.pack()
animate()
root.mainloop()
Related