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([...])
解析为位置参数。这失败了,因为位置参数在这里被读取为字符串。这就是您的堆栈跟踪告诉我们的内容。
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 版本将包含此修复程序
我正在尝试使用 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([...])
解析为位置参数。这失败了,因为位置参数在这里被读取为字符串。这就是您的堆栈跟踪告诉我们的内容。
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 版本将包含此修复程序