Python PIL ImageTk.PhotoImage() 为什么出现总线错误?

7 投票
3 回答
15145 浏览
提问于 2025-04-16 00:49

我在一台MacBook Pro上运行Python 2.6,想写一段代码在tkinter的图形界面上显示一个文件里的图片。这个图片叫做image.png。当我用下面这段代码时,程序运行得很顺利,没有任何错误:

i = Image.open("image.png")

但是当我加了一行代码后:

i = Image.open("image.png")
photo = ImageTk.PhotoImage(i)

程序就崩溃了,命令行上显示“Bus error”。我甚至不知道这是什么意思。我本以为PIL(Python Imaging Library)安装得没问题,因为Image可以正常工作,但ImageTk不行让我很困惑。有没有人能告诉我,是什么导致了这个Bus error?

编辑:我做了一个新程序来进一步测试这个错误。以下是我运行的确切脚本:

import Image
import ImageTk

i = Image.open("image.png")
photo = ImageTk.PhotoImage(i)

现在我不是收到“Bus error”,而是得到了这个追踪信息:

Traceback (most recent call last):
  File "imageTest.py", line 5, in <module>
    photo = ImageTk.PhotoImage(i)
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/PIL/ImageTk.py", line 113, in __init__
    self.__photo = apply(Tkinter.PhotoImage, (), kw)
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-tk/Tkinter.py", line 3285, in __init__
    Image.__init__(self, 'photo', name, cnf, master, **kw)
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-tk/Tkinter.py", line 3226, in __init__
    raise RuntimeError, 'Too early to create image'
RuntimeError: Too early to create image
Exception AttributeError: "PhotoImage instance has no attribute '_PhotoImage__photo'" in <bound method PhotoImage.__del__ of <ImageTk.PhotoImage instance at 0x3c7a30>> ignored

3 个回答

2

即使你需要调用一个Tk窗口,你也需要设置目录,这样它才能找到image.png这个文件。

import os
import Image 
import ImageTk
from Tkinter import Tk

os.chdir('C:/../../') # put file path for the image.

window = Tk()
i = Image.open("image.png") 
photo = ImageTk.PhotoImage(i)

window.mainloop()
6

ImageTk.PhotoImage 有一个垃圾回收(引用计数)的问题。你必须把 PhotoImage 对象的引用放在一个全局变量或者类的实例变量里(比如,self.myphoto = ImageTk.PhotoImage(i))。

请查看这个警告:

http://infohost.nmt.edu/tcc/help/pubs/pil/image-tk.html

7

我不太了解“总线错误”,但是在你调用 PhotoImage 之前,需要先创建一个 Tk 窗口。这个脚本对我来说是有效的-

import Image 
import ImageTk
from Tkinter import Tk

window = Tk()
i = Image.open("image.png") 
photo = ImageTk.PhotoImage(i)

撰写回答