Welcome, guest | Sign In | My Account | Store | Cart

Using PIL and Tkinter you can easily display images in a window.

Python, 43 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#!/usr/bin/env python

"""This is a small script to demonstrate using Tk to show PIL Image objects.
The advantage of this over using Image.show() is that it will reuse the
same window, so you can show multiple images without opening a new
window for each image.

This will simply go through each file in the current directory and
try to display it. If the file is not an image then it will be skipped.
Click on the image display window to go to the next image.

Noah Spurrier 2007
"""

import os, sys
import Tkinter
import Image, ImageTk

def button_click_exit_mainloop (event):
    event.widget.quit() # this will cause mainloop to unblock.

root = Tkinter.Tk()
root.bind("<Button>", button_click_exit_mainloop)
root.geometry('+%d+%d' % (100,100))
dirlist = os.listdir('.')
old_label_image = None
for f in dirlist:
    try:
        image1 = Image.open(f)
        root.geometry('%dx%d' % (image1.size[0],image1.size[1]))
        tkpi = ImageTk.PhotoImage(image1)
        label_image = Tkinter.Label(root, image=tkpi)
        label_image.place(x=0,y=0,width=image1.size[0],height=image1.size[1])
        root.title(f)
        if old_label_image is not None:
            old_label_image.destroy()
        old_label_image = label_image
        root.mainloop() # wait until user clicks the window
    except Exception, e:
        # This is used to skip anything not an image.
        # Image.open will generate an exception if it cannot open a file.
        # Warning, this will hide other errors as well.
        pass

The PIL Image class has a show() method to display an image. This works OK, but it is slow as it must save the image to a temporary file and then launch an external application to display it. What is even more annoying is that you cannot easily reuse the display window.

I often use PIL to create video filters that iterate over thousands of video frames. I like to display each frame after I am done processing it so I can observe how the image processing is progressing. You can't do this with Image.show() because you would end up with thousands of open windows.

Note that I'm using the Tkinter mainloop backwards from a typical event-oriented Tk application. Normally the Button event would control the iteration and display of file. Instead, I just break out of the mainloop. I do this because this way is simpler and better fits the model for a batch processing script. I just want to update a window with an image. I don't intend to have a more elaborate interface.

3 comments

black angel 16 years ago  # | flag

how to show next and back image? Thanks.But, how to show next image clicked to Button-1 and show back image clicked to Button-3 , or special key left-right ?

other.4.stuff 15 years, 1 month ago  # | flag

Nice piece of code, I would consider adding root.destroy() after the for-loop, to clean up a little. I know from running this on windows the window created just hangs on the screen and you cannot close it when it reaches the end of the loop.

Suresh 14 years, 2 months ago  # | flag

How will you modify this, if you want to show two images simultaneously? say side by side?