Search code examples
pythontkintercanvasimage.createimage

Load image using Tkinter in Python


I must be missing something, because my code doesn't work:

i have these 2 functions in a class compaClass:

def drawImgs(self):
    canvas1.delete("all")
    canvas1.create_image(0, 0, anchor=NW, image=newImg1)

def loadImg(self):
    global newImg1
    ...
    newImg1 = ImageTk.PhotoImage(resized_image1)

This thing worked well, but I thought: why using a variable outside the class? Why not using compaClass.img variable for it? It should be always available without declaring it globally. So I replaced newImg with self.img1. Now it doesn't draw anything, no error is returned - it looks a lot like original without global newImg1.

Any suggestions on what I've missed?

def drawImgs(self):
    canvas1.delete("all")
    canvas1.create_image(0, 0, anchor=NW, image=self.img1)

def loadImg(self):
    global newImg1
    ...
    self.img1 = ImageTk.PhotoImage(resized_image1)

Solution

  • An image created with ImageTk.PhotoImage and assigned to a variable that is local to a function or method is subject to garbage collection if no reference to the image object exists.

    1. Make sure that compaClass is stored in a variable as long as it's needed.
    2. Initialize self.img1 in your class' constructor and update it in loadImg().

    Revised code:

    import tkinter as tk
    from tkinter import Canvas
    from PIL import Image, ImageTk
    class CompaClass:
        def __init__(self, root):
            self.root = root
            self.canvas = Canvas(root, width=400, height=400)
            self.canvas.pack()
            self.img1 = None
        def draw_imgs(self):
            self.canvas.delete("all")
            if self.img1:
                self.canvas.create_image(0, 0, anchor=tk.NW, image=self.img1)
            else:
                print("No image has been loaded")
        def load_img(self, image_path):
            image = Image.open(image_path)
            resized_image = image.resize((400, 400))
            self.img1 = ImageTk.PhotoImage(resized_image)
            self.draw_imgs()
    root = tk.Tk() 
    app = CompaClass(root)
    app.load_img('your_path_to_the_image.jpg')
    root.mainloop()