PyZine
 


Article Finder
People
Issue 1 - Revision 1  /   Published in 2002 


 
  Py Links:
Latest Issue
Issue 08
Issue 07
Issue 06
Issue 05
Issue 04
Issue 02
Issue 01
 
 
Downloads
     
  Articles:
Throughout the quarter we cover topics of interest to Python developers.

  Scientific Python: Introducing Numeric

  Simple CGI Template Processing

  Extending Python with C: Part 1

  Image Viewing with TKinter

  Threading and the Global Interpreter Lock

 
 
 
     

Illustration by Lia Avant
Py Archive Article
Image Viewing Module with Tkinter

Image Viewing Module with Tkinter

- - - - - - - - - - - -

By Blake Garretson | Originally published in Py Issue 1

print

The one Python snippet that I reuse the most frequently is a small nine-line image viewer that I wrote. It is often useful to have the ability to display an image, even if you are just writing a command line program.

In the past, when I wrote programs that produced graphs or pictures, I had to rely on external software to view the result. After overcoming my fears about GUI programming, I now find that it is much more convenient to handle pictures right in my own code. You do not have to be a Tkinter expert in order to piece together a very simple image viewer. Here is the code for a basic viewer function:

Figure 1: Viewing and Image in TKinter
### viewimage.py
from Tkinter import *
def viewimage(filename):
    root = Tk()
    root.title("View Image")
    frame = Frame(root, colormap="new", visual='truecolor').pack()
    imagedata = PhotoImage(file=filename)
    label = Label(frame, image=imagedata).pack()
    quitbutton = Button(root, text="Quit", command=root.destroy).pack(fill=X)
    root.mainloop()

This handful of lines creates a new window called "root", adds a frame, places a label containing the image inside of the frame, and then puts a quit button at the bottom of the window.

Most of the code is self-explanatory, but a few important notes should be made. First, you must have Tkinter correctly installed and configured. (I won't get into the details here, but it should have been done for you if you are using any of the modern Python installations on Linux or Windows.). Secondly, you may have noticed the "visual='truecolor" parameter during the frame creation. This is necessary when you want to write portable code to display an image containing many colors. On some platforms, this is the default, but others will show the image with only 16 colors if you don't include the parameter. Also, note that this function only opens an image that has been saved to disk. Later, we can modify the program to get around this limitation.

Finally, a note about file formats. The standard Tkinter package only handles a few image formats. The supported formats are GIF (with and without transparency), grayscale PGM, and truecolor PPM. If you want to use any other formats, you will need to install the Python Imaging Library (PIL) available at www.pythonware.com. PIL adds the ability to read many common formats such as JPEG, PNG, BMP, TIFF, and many others. Using PIL is not anymore difficult than using Tkinter by itself. In the revised program below, I just call PIL's PhotoImage method instead of Tkinter's built-in one.

### viewimage.py
from Tkinter import *
#import PIL
import ImageTk                                               
def viewimage(filename):
    root = Tk()
    root.title("View Image")
    frame = Frame(root,colormap="new",visual='truecolor').pack()
    imagedata = ImageTk.PhotoImage(file=filename)            # Call PIL's PhotoImage function 
    label = Label(frame,image=imagedata).pack()
	 quitbutton = Button(root,text="Quit",command=root.destroy).pack(fill=X)
    root.mainloop()
###

Now the function will display any of the formats supported by PIL. You can get the full list of supported formats and the rest of the documentation at the Pythonware website.

Now let's try our new function in the context of a semi-useful program. I like to be on top of the weather, so I often view radar images that I get from the web. While manually surfing to the website will work, it becomes rather tedious if I do so several times a day. Why not let Python do the work for us? Go to a weather site such as www.accuweather.com and navigate to the radar image you want. Right click on the image to get the URL and plug it into the program below. This program uses the viewimage() function, so it should be imported or pasted into this program. Don't worry about the web-related functions, we just need them for demonstration purposes. You don't need to understand them to get the point.

### weathermap.py
import os, urllib, viewimage
RADAR_URL = “http://sirocco.accuweather.com/nxss_R1_640x480d/R1/inxR1kptks.gif"
mappic = urllib.urlretrieve( RADAR_URL,"delete-me.gif")
urllib.urlcleanup()
viewimage.viewimage("delete-me.gif")
os.remove("delete-me.gif")
    root = Tk()
    root.title("View Image")
    frame = Frame(root,colormap="new",visual='truecolor').pack()
    imagedata = ImageTk.PhotoImage(data=imagestring)
    label = Label(frame,image=imagedata).pack()
    quitbutton = Button(root,text="Quit",command=root.destroy).pack(fill=X)
    root.mainloop()

RADAR_URL = "http://sirocco.accuweather.com/nxss_R1_640x480d/R1/inxR1kptks.gif"
mappic = urllib.urlopen(RADAR_URL)
mapstring = mappic.read()
urllib.urlcleanup()
viewimage(mapstring)

This program highlights a limitation with our viewimage() function. In weathermap.py, we need to save an image file, just to delete it a few lines later. What a waste of IO. Lucky for us, the PhotoImage methods of Tkinter and PIL will accept files or raw data as input. In the next example program, we will dump the contents of the image directly into a variable instead of saving it to a file. Then we will view it with a modified version of viewimage.

The main difference in the viewimage() function is the use of the "data" parameter in the label definition instead of the "file" parameter. Instead of passing a filename as an argument to viewimage(), we just give it a string containing image data.

The limits of viewimage() are really only up to the user's creativity. Armed with this basic tool, you should be able to modify it to suit your needs. For example, if you test this program on a very large picture, you will probably notice the lack of any means to scroll the picture. As an exercise to the reader, try adding scrollbars to this program. (Hint: Try using a canvas widget instead of a label for storing the picture. Canvases have built-in support for scrolling.)

If you are using external viewers in your programs, take the plunge and try rolling your own. The extra versatility that you will gain will be well worth the investment in time. You will also be filled with the satisfaction of running a 100% Python program that stands on its own two feet.

This particular article is Copyright © 2002 Blake Garretson. All Rights Reserved.
Blake Garretson

uses Python on a daily basis for numerical analysis and utility programs. After getting a Master's degree in mechanical engineering, he took a job at the Dana Corporation as a finite element analyst. Besides his engineering duties, he finds himself performing system administration duties for a small group of Unix boxes.


shim
shim

 Py is committed to bringing you great Python Articles.

shim
shim


Home   Subscribe   Migration FAQ   Contact PyZine   Write for PyZine   ZopeMag   opensourcexperts.com  

Reproduction of material from any of PyZine's pages without prior written permission is strictly prohibited. Copyright 2003 - 2005 PyZine Zope/Plone hosting by Nidelven IT