Letting PIL and py2exe be friends
Escape from “cannot identify image file” hell
The Python Imaging Library (PIL) provides great image manipulation help for your python programs. Py2exe provides a smart way of turning a python script into a windows executable. There are times however when the resulting .exe will break if you don’t do the right thing.
I’d written a Python script, openpilwithdiag.py, which read TIFF files and worked just fine when run through the Python interpreter.
from PIL import Image im = Image.open("test.TIFF") print im.getcolors()
I then used py2exe to convert the script to a .exe. Aargh – when I went to run it I got an error :
IOError: cannot identify image file
It took a little digging around but it seems that when PIL constructs one of its PIL Image objects it searches a set of ‘image plugin’ files within the PIL installation. This is all good except that by the time py2exe has done it’s thing PIL (now nicely wrapped up inside the .exe) will be looking in the wrong place.
Pleasantly simple – given all the blind alleys I looked down to start with ! I’d previously had nasty problems using TIFF files with PIL and I think I started looking at this expecting the answer to be really nasty !
Whatever file formats you want to use import the corresponding PIL plugin directly into the script so that the instantiation of Image can ‘see’ them. For my example that’s like this :
from PIL import Image from PIL import TiffImagePlugin im = Image.open("test.TIFF") print im.getcolors()
Tried py2exe again and what do we get ?
C:\>openpilwithdiag.exe [(37306, (76, 25, 12, 51)), (42810, (0, 0, 0, 255)), (1489484, (0, 0, 0, 0))]
Much better !
The set of possible plugins may be found by looking for files named xImagePlugin.py (where x is the name of the supported format) within the sub-directory of your Python installation at :
<your python directory>\Lib\site-packages\PIL
A list of file formats PIL supports is seen in the appendix of the PIL Handbook
It occurs to me that for anyone who’s never touched py2exe it might be worth posting the setup.py I was using to drive the py2exe process – so here it is :
from distutils.core import setup import glob import py2exe setup(console=['openpilwithdiag.py'], data_files= )