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

Imagetk.PhotoImage crashes on Python 3.5 + Tk/Tcl 8.6

我正在尝试使用 Pillow 在 Tkinter 中显示图像,但出现奇怪的错误:"Process finished with exit code -1073741819 (0xC0000005)" 并且 Tkinter window 从未出现。

这是代码(已简化到最大程度):

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 window 出现当我关闭 Tk window).

时,退出代码为 0

如有任何帮助,我们将不胜感激。

编辑:根据 user5510752 的建议,我将 i_tk = ImageTk.PhotoImage(i) 更改为 i_tk = tkinter.PhotoImage(i)。问题现在已经从我制作 PhotoImage 的地方转移到我将它插入 canvas.

的地方

这是新代码:

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 加载到 canvas 而不是 c.p,代码不会出错并且我得到一个空的 canvas.

[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 canvas 中显示一个 jpg 文件,请只 post Tcl/Tk 的版本, libjpeg 和 Pillow 你正在使用。我怀疑这可能只是因为两个模块在我当前的 Python 3 配置中不兼容。

大多数 tkinter 函数已更改 python 3,您的变量 i_tk 必须是这样的:

i_tk = tkinter.PhotoImage(i)

看看这个 question

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

如您在堆栈跟踪中所见,错误发生在参数和关键字参数映射之外的位置 (*args**kwargs)。因为您只是传递不带关键字的图像,它会尝试将您的 Image.open([...]) 解析为位置参数。这失败了,因为位置参数在这里被读取为字符串。这就是您的堆栈跟踪告诉我们的内容。

一看documentation:

The PhotoImage class can read GIF and PGM/PPM images from files

您的原始代码应该可以完美运行,但似乎有些问题 Pillow 或 Tk 错误。

无论如何,如果没有 ImageTk.PhotoImage() 就无法加载 jpg,因此在有人了解导致崩溃的原因之前,无法使用 Pillow 和 Tk 解决它。

我对 pillow 3.0 车轮也有同样的问题,但这对我来说并不是很重要...

JFYI 调用堆栈: https://gist.github.com/DoumanAsh/6dba8411a109fbc68197

P.s。我的设置和你一样。而且我怀疑 Win 平台上的 python 3.5 应该只使用 Tk 8.6,因为 windows 包已使用 Tcl 8.6.3 更新并且引入了 Tcl 对 Win10

的支持

更新:

问题已解决https://github.com/python-pillow/Pillow/pull/1553

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