[Image-SIG] Need help with PhotoImage (PIL), Tkinter and large JPGs - (it crashes)

Joel Gould joelg@alum.mit.edu
Mon, 12 Mar 2001 13:44:23 -0500


I also posted this problem to the comp.lang.python newsgroup.  I am sorry
for the double posting.

I am having trouble developing a simple JPG manipulation program in Python
using PIL (Python Imaging Library) and Tkinter.  Any advice would be
appreciated.

When I try to display JPG images, I run into two problems:
(1) With large images I just crash, and
(2) With smaller images, I see image corruption.

Joel Gould
joelg@alum.mit.edu

========== Here is the crash details ===============

If I load a 3.3 megapixel JPG file into a PIL (Python Image Library)
PhotoImage object and then draw that on a Tkinter.Canvas object, Python
crashes with an access violation (under Windows 98).

I have attached the code that fails. You can get a suitable image from this
link:
http://www.gouldhome.com/Travel/StThomas00/images/001229_1106_charlotteAmali
e3.jpg

I have tried this using the latest py20 distribution (Python 2.0, PIL 1.1.1,
etc.) from Secret Labs.  I also tried it using the PythonWorks Testdrive 1.1
(which uses Python 1.5.2) also from Secret Labs.

I am using Windows 98 SE on a Pentium III with 256MB of RAM.

Can anyone tell me why this is failing?

P.S.  I know the image is very big and I can make it smaller before
displaying it.  I just do not think it should GPF in this case.

----- snip ----

import Tkinter
import Image
import ImageTk

class MainDialog:
    def __init__(self, parent):
        self.canvas = Tkinter.Canvas(parent,width=700,height=500)
        self.canvas.pack()
        self.image = Image.open("001229_1106_charlotteAmalie3.jpg")
        self.tkim = ImageTk.PhotoImage(self.image)
        self.item = self.canvas.create_image(
            0,0,image=self.tkim,anchor='nw')

if __name__ == '__main__':
    root = Tkinter.Tk()
    dialog = MainDialog(root)
    root.mainloop()

========== Here is the corruption details ===============

I have noticed corruption of displayed imaged when using the PhotoImage
object from PIL (Python Image Library) under Tkinter.

I am using Windows 98 SE with 256 MB or RAM.  I see the effect under Python
2.0 (using the latest Py20 Windows binaries).

I have attached a sample program which fails for me.  The failure symptom is
that the lower 10% of some of the images is corrupted with noise as you
cycle through the images (pressing the button).  Not every image is
corrupted and the corruption pattern changes even when you get back to the
same image.

You can get the images from:
http://www.gouldhome.com/Travel/StThomas00/images/001229_1106_charlotteAmali
e1.jpg
http://www.gouldhome.com/Travel/StThomas00/images/001229_1106_charlotteAmali
e2.jpg
http://www.gouldhome.com/Travel/StThomas00/images/001229_1106_charlotteAmali
e3.jpg
http://www.gouldhome.com/Travel/StThomas00/images/001229_1106_charlotteAmali
e4.jpg

Attached is the code sample.  I would appreciate it if anyone could tell me
what is wrong.

----- snip -----

import Tkinter
import Image
import ImageTk

imageList = [
    "001229_1106_charlotteAmalie1.jpg",
    "001229_1106_charlotteAmalie2.jpg",
    "001229_1106_charlotteAmalie3.jpg",
    "001229_1106_charlotteAmalie4.jpg",
    ]

class MainDialog:

    def __init__(self, parent):
        self.canvas = Tkinter.Canvas(parent,width=800,height=600)
        self.canvas.pack()

        self.images = []
        for name in imageList:
            image = Image.open(name)
            image.thumbnail( (800,600) )
            self.images.append(image)

        self.currentImage = 0
        self.tkim = ImageTk.PhotoImage(self.images[self.currentImage])
        self.item = self.canvas.create_image(
            0,0,image=self.tkim,anchor='nw')

        button = Tkinter.Button(parent,
            text='Next Image', command=self.onNewImage)
        button.pack()

    def onNewImage(self):
        self.currentImage = self.currentImage + 1
        if self.currentImage >= len(self.images):
            self.currentImage = 0
        self.tkim = ImageTk.PhotoImage(self.images[self.currentImage])
        self.item = self.canvas.create_image(
            0,0,image=self.tkim,anchor='nw')

if __name__ == '__main__':
    root = Tkinter.Tk()
    dialog = MainDialog(root)
    root.mainloop()