Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to insert an image using Canvas in Tkinter?

I am trying to insert an image in my python application using Canvas in tkinter. The code for the same is:

class Welcomepage(tk.Frame):

def __init__(self, parent, controller):
    tk.Frame.__init__(self,parent)
    canvas = tk.Canvas(self, width = 1000, height = 1000, bg = 'blue')
    canvas.pack(expand = tk.YES, fill = tk.BOTH)
    image = tk.PhotoImage(file="ice_mix.gif")
    canvas.create_image(480, 258, image = image, anchor = tk.NW)

The image is getting read from the source but still not getting displayed in the frame.I am new to the GUI programming someone please help me out.

like image 806
Ayush Mishra Avatar asked Dec 11 '25 08:12

Ayush Mishra


2 Answers

The likely issue here is that the image is being garbage collected by Python and therefore not being displayed - which is what @nae's comment is suggesting. Attaching it to the self reference will stop it from being garbage collected.

self.image = tk.PhotoImage(file="ice_mix.gif")  # Use self.image
canvas.create_image(480, 258, image = self.image, anchor = tk.NW)

The Tkinter Book on effbot.org explains this:

Note: When a PhotoImage object is garbage-collected by Python (e.g. when you return from a function which stored an image in a local variable), the image is cleared even if it’s being displayed by a Tkinter widget.

To avoid this, the program must keep an extra reference to the image object. A simple way to do this is to assign the image to a widget attribute, like this:

label = Label(image=photo) 
label.image = photo # keep a reference!
label.pack()
like image 125
Will Keeling Avatar answered Dec 13 '25 20:12

Will Keeling


  1. If You still need to use a Canvas instead a Label for image placement inside a function or a method You can use an external link for image, and use a global specificator for this link inside a function.
  2. You may need to use SE anchor, not NW.

This code works successfully (gets an OpenCV image from USB-camera and place it in a Tkinter Canvas):

def singleFrame1():
    global imageTK      # declared previously in global area
    global videoPanel1  # also global declaration (initialized as "None")
    videoCapture=cv2.VideoCapture(0)
    success,frame=videoCapture.read()
    videoCapture.release()
    vHeight=frame.shape[0]
    vWidth=frame.shape[1]
    imageRGB=cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)  # OpenCV RGB-image
    imagePIL=Image.fromarray(imageRGB)              # PIL image
    imageTK=ImageTk.PhotoImage(imagePIL)            # Tkinter PhotoImage
    if videoPanel1 is None:
        videoPanel1=Canvas(root,height=vHeight,width=vWidth)  # root - a main Tkinter object
        videoPanel1.create_image(vWidth,vHeight,image=imageTK,anchor=SE)
        videoPanel1.pack()
    else:
        videoPanel1.create_image(vWidth,vHeight,image=imageTK,anchor=SE)
like image 24
Peter Nazarenko Avatar answered Dec 13 '25 20:12

Peter Nazarenko



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!