[Image-SIG] PB whith PIL and py2exe

Georg Mischler schorsch@schorsch.com
Thu, 23 Aug 2001 12:53:58 -0400 (EDT)


Brice Cassagnab=E8re wrote:

> I am using python 21 and PIL1.1.2
>
> I have got a littel problem with the Image.py file:
>     In my script version it works without errors;
>     But when I compile my script whith py2exe , I have an error in this f=
ile (Image.py)
>
> At this momment the script just call the open method to open an *.bmp.
>
> I have got the error :
>
> Traceback (most recent call last):
>   File "ui\VoxchatManagerMonitoringNb.pyc", line 146, in EvtMake
>   File "ui\VoxchatManagerReportParserUi.pyc", line 57, in __init__
>   File "ui\VoxchatManagerMonitoringNb.pyc", line 170, in TraceStat
>   File "PIL\Image.pyc", line 960, in open
> IOError: cannot identify image file
>
> I tried to debug the the Image.py file to see how it works...
> I think tha the problem is in the fonction preinit() wich is called line =
938
> : Before it, the ID list and the OPEN dictionnary are empty. In the scrip=
t
> execution, the fonction preinit() initialize ID (['BMP', ......]  and OPE=
N (I
> didn't manage to find how...) .When i execute the compiled version ( comp=
iled
> with py2exe) ID ans OPEN are still empty after the preinit() fonction >>>=
>
> the instruction for i in ID is not executed and I obtain : raise IOError,
> "cannot identify image file"
>
> Do you have a solution (patch) or can you explain me how the preinit()
> function works.* Thanks


The preinit() function is only part of the problem, it works together
with the following init() function. In init(), the PIL directory is
searched for all files that have a name ending with "*ImagePlugin.py",
and those are then imported one by one until one is found that can
load your file. The problem is, that in a frozen package, those
files can't be found in a directory, but the init() function must
get the information about which are available from some other source.

I am not aware of a clean solution here. What I did was to hack the
init() function as follows. You will also have to instruct py2exe
to include all the existing plug-in files in your frozen archive.


---- hacked excerpt from Image.py ----

def init():
    "Load all file format drivers."

    global _initialized
    if _initialized >=3D 2:
    return

    import os, sys

    # only check directories (including current, if present in the path)

    rf_plugins =3D [ # gm - ugly hack for pyz packing.
"ArgImagePlugin.py",     "BmpImagePlugin.py",  "CurImagePlugin.py",
"DcxImagePlugin.py",     "EpsImagePlugin.py",  "FliImagePlugin.py",
"FpxImagePlugin.py",     "GbrImagePlugin.py",  "GifImagePlugin.py",
"IcoImagePlugin.py",     "ImImagePlugin.py",   "ImtImagePlugin.py",
"IptcImagePlugin.py",    "JpegImagePlugin.py", "McIdasImagePlugin.py",
"MicImagePlugin.py",     "MpegImagePlugin.py", "MspImagePlugin.py",
"PcdImagePlugin.py",     "PcxImagePlugin.py",  "PdfImagePlugin.py",
"PixarImagePlugin.py",   "PngImagePlugin.py",  "PpmImagePlugin.py",
"PsdImagePlugin.py",     "SgiImagePlugin.py",  "SunImagePlugin.py",
"TgaImagePlugin.py",     "TiffImagePlugin.py", "WmfImagePlugin.py",
"XVThumbImagePlugin.py", "XbmImagePlugin.py",  "XpmImagePlugin.py",
]
    for path in filter(os.path.isdir, sys.path):
    #for file in os.listdir(path):
    for file in rf_plugins: # gm
        if file[-14:] =3D=3D "ImagePlugin.py":
        p, f =3D os.path.split(file)
        f, e =3D os.path.splitext(f)
        try:
            sys.path.insert(0, path)
            try:
            #__import__(f, globals(), locals(), [])
            __import__(f, globals(), locals(), ["PIL"]) # gm
            finally:
            del sys.path[0]
        except ImportError:
            if DEBUG:
            print "Image: failed to import",
            print f, ":", sys.exc_value

    if OPEN or SAVE:
    _initialized =3D 2

---- end of excerpt ----

Not pretty, but it works for me. Note that you have to make sure
that the list reflects those plug-ins that you actually have on
your system, which may or may not be the same as on mine.
Of course, an automatic mechanism for switching to a preset list
when freezing PIL would be much better. Maybe someone smarter
than me will invent one...


Have fun!

-schorsch

--=20
Georg Mischler  --  simulations developer  --  schorsch at schorsch.com
+schorsch.com+  --  lighting design tools  --  http://www.schorsch.com/