Imagetk.PhotoImage在Python 3.5 + Tk / Tcl 8.6上崩溃

时间:2015-10-31 05:57:30

标签: python tkinter pillow

我试图使用Pillow在Tkinter中显示图像,但我得到一个奇怪的错误:"处理完成后退出代码-1073741819(0xC0000005)"并且Tkinter窗口永远不会出现。

这里是代码(简化为最大值):

from PIL import Image, ImageTk
from tkinter import Tk

t = Tk()
i = Image.open('data/pic.jpg') # small picture (29kb, 100x100px)
i_tk = ImageTk.PhotoImage(i) # The problem disappears when this line is commented out.
t.mainloop()

我在Windows 10上使用Python 3.5,Tcl / Tk 8.6,Pillow 3.0.0(全部为64位)

同样的脚本(用Tkinter替换tkinter)在Python 2.7.9,Tcl / Tk 8.5和Pillow 2.9.0的同一台机器上运行完美(当我关闭Tk窗口时出现Tk窗口并且退出代码为0 )。

非常感谢任何帮助。

编辑:根据用户5510752的建议,我将i_tk = ImageTk.PhotoImage(i)更改为i_tk = tkinter.PhotoImage(i)。问题现在已从我制作PhotoImage的地方转移到我将其插入画布的位置。

这是新代码:

from PIL import Image
from tkinter import Tk, PhotoImage, Canvas

t = Tk()
c = Canvas(t, bg="blue")
c.grid(sticky="news")

c.i = Image.open("data/pic.jpg")
c.p = PhotoImage(c.i)
c.create_image(0, 0, image=c.p) # errors out here

t.mainloop()

这会出现此错误TypeError: __str__ returned non-string (type JpegImageFile)

Traceback (most recent call last):
  File "D:/Workspace/PythonProjects/Puzzle 3.5/main.py", line 29, in <module>
    c.create_image(0, 0, image=c.p)
  File "C:\Python 3.5\lib\tkinter\__init__.py", line 2328, in create_image
    return self._create('image', args, kw)
  File "C:\Python 3.5\lib\tkinter\__init__.py", line 2319, in _create
    *(args + self._options(cnf, kw))))
TypeError: __str__ returned non-string (type JpegImageFile)

我为Python 3查看了这个函数的不同签名,但我找不到任何东西。这行虽然适用于Python 2.7(使用ImageTk.PhotoImage)。更奇怪的是,如果我尝试将c.i加载到画布而不是c.p中,则代码不会出错并且我得到一个空画布。

[EDIT2]

根据R4PH43L的建议,我试过:

from tkinter import Tk, PhotoImage, Canvas

t = Tk()
c = Canvas(t, bg="blue")
c.grid(sticky="news")

c.p=PhotoImage(file="data/pic.jpg")
c.create_image(0, 0, image=c.p) # errors out here

t.mainloop()

这给出了一个新错误:

Traceback (most recent call last):
  File "D:/Workspace/PythonProjects/Puzzle 3.5/main.py", line 28, in <module>
    c.p=PhotoImage(file="data/pic.jpg")
  File "C:\Python 3.5\lib\tkinter\__init__.py", line 3393, in __init__
    Image.__init__(self, 'photo', name, cnf, master, **kw)
  File "C:\Python 3.5\lib\tkinter\__init__.py", line 3349, in __init__
    self.tk.call(('image', 'create', imgtype, name,) + options)
_tkinter.TclError: couldn't recognize data in image file "data/pic.jpg"

我每次尝试使用不同的JPEG都无济于事。这次我也尝试使用GIF并且它有效(但我需要打开JPEG,所以......)。值得注意的是libjpeg已安装在我的机器上,Pillow似乎没有使用它(除非我将图片传递给ImageTk,然后我们回到原来的错误)

PS:如果有人设法在python 3.5中的tkinter画布中显示jpg文件,请发布您正在使用的Tcl / Tk,libjpeg和Pillow的版本。我怀疑这可能只是由于我目前的Python 3配置中的两个模块不兼容。

3 个答案:

答案 0 :(得分:0)

对于python 3,大多数tkinter函数都已更改,您的变量i_tk必须如下:

i_tk = tkinter.PhotoImage(i)

答案 1 :(得分:0)

看看这个question

尝试将图片创建为c.p=tkinter.PhotoImage(file="data/pic.jpg")

正如您在堆栈跟踪中看到的那样,错误发生在参数和关键字参数(*args**kwargs)的映射之外。因为你只是传递没有关键字的图像,它会尝试将你的Image.open([...])解析为位置参数。由于位置参数在此处被读取为字符串,因此失败。这就是你的堆栈跟踪告诉我们的内容。

一看documentation

  

PhotoImage类可以从文件中读取 GIF和PGM / PPM 图像

答案 2 :(得分:0)

您的原始代码应该可以正常运行,但似乎有一些东西 Pillow或Tk错了。

无论如何你不能在没有ImageTk.PhotoImage()的情况下加载jpg,所以没有办法用Pillow和Tk来解决它,直到有人知道导致崩溃的原因。

我对枕头3.0车轮也有同样的问题,但它对我来说并不是真的很重要......

JFYI callstack: https://gist.github.com/DoumanAsh/6dba8411a109fbc68197

P.S。我有与你相同的设置。我怀疑Win平台上的python 3.5应该只使用Tk 8.6,因为Windows bundle已经用Tcl 8.6.3更新了并且引入了Tcl对Win10的支持

<强> UPD:

问题已修复https://github.com/python-pillow/Pillow/pull/1553

我假设3.0.1版本将包含此修复