Images in Tkinter

Tkinter uses PhotoImage objects to display pictures. If you have a *.bmp (bitmap) picture file, you can create the PhotoImage directly within Tkinter:

http://effbot.org/tkinterbook/photoimage.htm

Example of putting a gif image into a label:

from Tkinter import *

#using Toplevel() instead of Tk() for Python 3
root = Toplevel()

#must be a gif file
photo = PhotoImage(file="cat.gif")
L1 = Label(root, image=photo)

#this line prevents garbage collection from memory
L1.photo = photo

L1.pack()

root.mainloop()

If you have an image other than a gif, you can either save it as a gif (use Paint or whatever) or load it as a PIL object first.

Add jpg image to a Canvas
(works for image formats other than *.gif)

from Tkinter import *
import PIL
import PIL.ImageTk

#Load image as PIL, then create PhotoImage from that

root = Toplevel()
catPIL = PIL.Image.open('nothappy.jpg')
cat = PIL.ImageTk.PhotoImage(catPIL)

canvas = Canvas(root, width=300, height=300)
canvas.grid(row=0, column=0)

#Tkinter uses PhotoImage objects
#anchor is the the part of image that goes at (x,y)
canvas.create_image((50,50), image=cat, anchor='nw')

root.mainloop()

Display a jpg in a label when button is clicked:

import PIL
import PIL.ImageTk
from Tkinter import *

def showcat():
    label1['image'] = catTk

root = Toplevel()

catPIL = PIL.Image.open('cat.jpg')
catTk = PIL.ImageTk.PhotoImage(catPIL)

b1 = Button(root, text="click for cat image", command=showcat)
b1.pack()

label1 = Label(root, text="no image yet")
label1.pack()

root.mainloop()

Timing Issues – results in blank picture

If you try to load an image inside a function and then immediately display it, you can have issues with timing since it takes time for the image to load. Python tries to display the image before it’s done loading. One way to avoid that is to load your image objects at the start of the program and then include only the commands to display them inside your event function.

The example above works properly because the PIL image object and ImageTk.PhotoImage objects are loaded into memory ahead of time. Here’s that example above with some comments to explain:

import PIL
import PIL.ImageTk
from Tkinter import *

#catTk loaded previously - displays properly
def showcat():
    label1['image'] = catTk

root = Toplevel()

#load image as PIL object
catPIL = PIL.Image.open('cat.jpg')

#convert PIL object to PIL.ImageTk.PhotoImage
#this command is outside the button function
#must be after root = Tk()
catTk = PIL.ImageTk.PhotoImage(catPIL)

b1 = Button(root, text="click for cat image", command=showcat)
b1.pack()

label1 = Label(root, text="no image yet")
label1.pack()

root.mainloop()

This is the same example, but it’s trying to load the images into memory in the showcat() function. This doesn’t work properly:

import PIL
import PIL.ImageTk
from Tkinter import *

#Won't work - image will be blank
def showcat():
    catPIL = PIL.Image.open('cat.jpg')
    catTk = PIL.ImageTk.PhotoImage(catPIL)
    label1['image'] = catTk

root = Toplevel()

b1 = Button(root, text="click for cat image", command=showcat)
b1.pack()

label1 = Label(root, text="no image yet")
label1.pack()

root.mainloop()