Fade between images on screen using Python TKinter / imageTK
Question: I am a python newbie and have been making a somewhat odd slideshow script that
cycles through images and also sources a variable from another file to
'settle' on an image.

I'm sure my code is tragic. But it does work (see below)!

My question is - how would I make it fade between images instead of the jerky
go to white momentarily then to next image which it does currently? Is there a
transitions module I should look at?

    
    
    from Tkinter import *
    import Image, ImageTk, random, string
    
    class MyApp(Tk):
    
    def __init__(self):
        Tk.__init__(self)
        fr = Frame(self)
        fr.pack()
        self.canvas  = Canvas(fr, height = 400, width = 600)
        self.canvas.pack()
    
        self.old_label_image = None
        self.position = 0
        self.command = 0
        self.oldcommand = 0
    
        self.slideshow()
        self.debug()
    
    def debug(self):
        self.QUIT = Button(self)
        self.QUIT["text"] = "QUIT!" + str(self.command)
        self.QUIT["fg"]   = "red"
        self.QUIT["command"] =  self.quit
    
        self.QUIT.pack({"side": "right"})
    
    def slideshow (self):
    
        if self.command != self.oldcommand:
            self.after_cancel(self.huh)
            # run through random between 2-5 changes 
            # then settle on command for 30 seconds
            self.title("Title: PAUSE")
            self.oldcommand = self.command
            self.slideshow()
        else:
            file = str(self.position) + '.jpg'
            image1 = Image.open(file)
            self.tkpi = ImageTk.PhotoImage(image1)
            label_image = Label(self, image=self.tkpi)
            label_image.place(x=0,y=0,width=image1.size[0],height=image1.size[1])
            self.title("Title: " + file)
    
            if self.old_label_image is not None:
                self.old_label_image.destroy()
            self.old_label_image = label_image
    
            # make this random instead of pregressional
            if self.position is not 1:
                self.position = self.position + 1
            else:
                self.position = 0
    
            commandfile = open('command.txt', 'r')
            self.command = string.atoi(commandfile.readline())
            commandfile.close()
    
            int = random.randint(2000, 5000)
            self.huh = self.after(int, self.slideshow)
            #self.after_cancel(huh) - works ! so maybe can do from below Fn?
    
    if __name__ == "__main__":
    root = MyApp()
    root.mainloop()
    


Answer: This can be achieved using the blend function.

    
    
     Image.blend(image1, image2, alpha) ⇒ image
    

Creates a new image by interpolating between the given images, using a
constant alpha. Both images must have the same size and mode.

    
    
    out = image1 * (1.0 - alpha) + image2 * alpha
    

If the alpha is 0.0, a copy of the first image is returned. If the alpha is
1.0, a copy of the second image is returned. There are no restrictions on the
alpha value. If necessary, the result is clipped to fit into the allowed
output range.

So you could have something like this:

    
    
    alpha = 0
    while 1.0 > alpha:
        image.blend(img1,img2,alpha)
        alpha = alpha + 0.01
        label_image.update()
    

An example is here, havn't had time to test this but you get the idea-

    
    
    from PIL import image
    import time
    white = image.open("white_248x.jpg")
    black = image.open("black_248x.jpg")
    new_img = image.open("white_248x.jpg")
    root = Tk()
    image_label = label(root, image=new_img)
    image_label.pack()
    alpha = 0
    while 1.0 > alpha:
        new_img = image.blend(white,black,alpha)
        alpha = alpha + 0.01
        time.sleep(0.1)
        image_label.update()
    root.mainloop()
    

