I wanted to do an image viewer for a photo catalog project. Here is the code:

import Image, ImageTk
from Tkinter import *

filename = "C:/Pictures/2006/2006.07.04/E clarus 1 crop.jpg"

class MyFrame(Frame):

    def __init__(self, master):
        Frame.__init__(self, master)
        im = Image.open(filename) # <--- chokes!
        im.resize(250,150)
        self.image = Label(self, image=ImageTk.PhotoImage(im))
        self.image.grid()
        self.grid()

        

mainw = Tk()
mainw.frame = MyFrame(mainw)
mainw.mainloop()

Here is the error message:

Traceback (most recent call last):
  File "C:\Python24\imager.py", line 19, in -toplevel-
    mainw.frame = MyFrame(mainw)
  File "C:\Python24\imager.py", line 10, in __init__
    im = Image.open(filename)
AttributeError: class Image has no attribute 'open'

which of course is nonsense, since (a) class Image certainly does have an 'open' method, and (b) I can run the offending code in interactive mode and get a result.

What gives?

Thanks,
Jeff

P.S. To add to the mystery, here is the slightly modified code out of the Scripts directory that came with the PIL module. It works fine (of course!)

#
# The Python Imaging Library
# $Id: pilview.py 2134 2004-10-06 08:55:20Z fredrik $
#

from Tkinter import *
import Image, ImageTk

#
# an image viewer

class UI(Label):

    def __init__(self, master, im):

        if im.mode == "1":
            # bitmap image
            self.image = ImageTk.BitmapImage(im, foreground="white")
            Label.__init__(self, master, image=self.image, bg="black", bd=0)

        else:
            # photo image
            self.image = ImageTk.PhotoImage(im)
            Label.__init__(self, master, image=self.image, bd=0)

#
# script interface

import sys

if not sys.argv[1:]:
##    print "Syntax: python pilview.py imagefile"
##    sys.exit(1)
    filename = "C:/Pictures/2006/2006.07.04/E clarus 1 crop.jpg"
else:
    filename = sys.argv[1]

root = Tk()
root.title(filename)
im = Image.open(filename)  <--- !!! works!

UI(root, im).pack()

root.mainloop()

OK, the one problem is solved, while another presents. It turns out that the import order mattered:

from Tkinter import *
import Image, ImageTk   # <--- has to be second to overwrite Tkinter.Image


filename = "C:/Pictures/2006/2006.07.04/E clarus 1 crop.jpg"

class MyFrame(Frame):

    def __init__(self, master, im):
        Frame.__init__(self, master)
        im.resize((250,150))  # <--- bug in original code: must be tuple
        self.image = Label(self, image=ImageTk.PhotoImage(im))
        self.image.grid()
        self.grid()

        
im = Image.open(filename)
mainw = Tk()
mainw.frame = MyFrame(mainw, im)
mainw.mainloop()

But now, the image comes out blank. Harrumph.

Fixed. Solution notes below:

from Tkinter import *
import Image, ImageTk


filename = "C:/Pictures/2006/2006.07.04/E clarus 1 crop.jpg"

class MyFrame(Frame):

    def __init__(self, master, im):
        Frame.__init__(self, master)
        im=im.resize((250,150))  # <--- resize() is a non-destructive method; returns resized image instead of changing im directly.
        self.caption = Label(self, text="caption")
        self.caption.grid()
        self.image = ImageTk.PhotoImage(im)  # <--- results of PhotoImage() must be stored
        self.image_label = Label(self, image=self.image, bd=0) # <--- will not work if 'image = ImageTk.PhotoImage(im)'
        self.image_label.grid()
        self.grid()

        
im = Image.open(filename)
mainw = Tk()
mainw.frame = MyFrame(mainw, im)
mainw.mainloop()

Rather finicky, IMO.

Jeff

Thanks Jeff!
I had made myself a note when using PIL and Tkinter not to use
'from Tkinter import *' but the simple 'import Tkinter as tk' to avoid namespace conflicts with Image.

Your other observations are rather astute!

Okay, I have a question:

Is there any way to resize an image using only Tkinter?

This question stems from a deeper root problem -- I can't actually seem to get PIL to install. I keep getting the following error:

unable to execute gcc: No such file or directory
error: command 'gcc' failed with exit status 1

I can't find 'gcc' in the setup.py file, so I'm at a loss for what to do.

This question has already been answered. Start a new discussion instead.