Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fade between images on screen using Python TKinter / imageTK

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()
like image 969
Staple Avatar asked Mar 21 '26 03:03

Staple


1 Answers

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()
like image 184
Dan Weston Avatar answered Mar 23 '26 16:03

Dan Weston



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!