X11 Tkinter + PIL + py2app = IOError 无法识别图像文件
我在使用一个Python程序(版本是2.7.3,使用X11 Tkinter,py2app 0.6.4,MacOS X 10.7.4)时遇到了问题,我想把它导出到py2app。这个问题只在独立的py2app应用版本中出现。当我直接运行这个程序的源文件时,问题就不存在,所以我觉得这可能和py2app的导出有关。
问题是:当我启动图形用户界面(GUI),第一次尝试加载一个有效的图像文件时,图像无法加载,并且我收到了来自PIL图像模块的以下错误:
File "Image.pyc", line 1980, in open
IOError: cannot identify image file
然后我在没有关闭GUI的情况下,尝试打开同一个文件,这次加载就完全正常,没有任何错误或问题。每次都是这样,不管我尝试哪个图像文件 - 第一次加载失败,后续的尝试都成功。我还要补充的是,在第一次出错之后,没有任何图像文件会再加载失败 - 即使它们和第一个文件不同。
几点说明:
- 这个图像文件是一个序列,文件非常大(大约300 MB),所以为了加快加载速度,我使用了mmap。我尝试过去掉mmap步骤,直接把一个普通的文件对象传给ImagePIL.open,问题依旧存在。
- 我还尝试在传给ImagePIL.open之前先把文件指针移到文件开头,但没有任何效果。
- py2app的设置文件很简单 - 只包含了一些配置文件和一个图标。
这是出问题的图像加载函数的相关部分:
import Image as ImagePIL
import mmap as m
...
...
def loadImage(self):
errorLog.debug("Attempting to open image \""+self.filenameVar.get()+"\"")
try:
if self.fileMap is not None:
self.fileMap.close()
imageFile = open(self.filenameVar.get(), 'r')
self.fileMap = m.mmap(imageFile.fileno(), 0, prot=m.PROT_READ)
# self.fileMap.seek(0)
self.imageSeries = ImagePIL.open(self.fileMap)
imageFile.close()
except(IOError):
errorLog.exception("Failed to open image \""+self.filenameVar.get()+"\"")
return
我现在有点困惑 - 有什么想法吗?提前谢谢!
补充:我还要补充一下,Tkinter、PIL和py2app是通过MacPorts 2.1.2安装的,希望这能有所帮助。
2 个回答
这个问题是因为Pillow 3.0.0版本和py2app之间不兼容导致的。
我建议有两个解决办法来避免使用PIL(Pillow):
- 用opencv代替PIL。
- 卸载当前的Pillow版本,然后安装一个旧版本,比如1.7.8。
看起来,py2app在打包应用程序时并没有把PIL的图像插件包含进去,尽管py2app的一个配方是试图确保它们被包含。
你可以尝试用“python setup.py py2app --packages=PIL”来构建,然后用“import PIL.Image as ImagePIL”来使用它。
我还不明白为什么PIL的配方不起作用,可能是因为MacPorts在构建python包时的某些方式(我自己不使用MacPorts)。