【问题标题】:Imagetk.PhotoImage crashes on Python 3.5 + Tk/Tcl 8.6Imagetk.PhotoImage 在 Python 3.5 + Tk/Tcl 8.6 上崩溃
【发布时间】:2016-01-31 14:53:33
【问题描述】:

我正在尝试使用 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 加载到画布中,代码不会出错并且我得到一个空画布。

[编辑2]

按照 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 配置中不兼容。

【问题讨论】:

  • 您缺少前导斜杠 Image.open('/data/pic.jpg')
  • 我试过了,但是找不到带斜线的图片。
  • 请给我们完整的错误信息,包括。调用栈
  • @R4PH43L:对不起,我忘了添加它。现在已经完成了。希望它有所帮助:)

标签: python tkinter pillow


【解决方案1】:

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

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

枕头 3.0 轮子也有同样的问题,但这对我来说并不重要......

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

附:我的设置和你一样。而且我怀疑 Win 平台上的 python 3.5 应该只使用 Tk 8.6,因为 Windows 包是用 Tcl 8.6.3 更新的,并且引入了 Tcl 对 Win10 的支持

UPD:

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

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

【讨论】:

  • 对不起,我还不能对你的答案投赞成票,但如果可以的话,我会的。感谢您的建设性回答:-)。现在我知道这与我的安装无关。我最终为我的项目恢复到 Python 2.7.9,除了一些我无法使用的 Python 3 的漂亮技巧之外,一切都很好。我希望他们能解决它。
  • (不过我接受了,因为我还没有看到更好的答案)
  • 你的问题让我想起了这个问题,并把它提出给枕头人。也许他们会有一些建议:github.com/python-pillow/Pillow/issues/1549
  • 我也遇到了同样的问题(Windows 10、Python 3.5)。我升级到 Pillow 3.2.0,现在一切正常。
【解决方案2】:

看看这个question

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

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

一看documentation

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

【讨论】:

  • 感谢您的链接和建议。我仔细阅读了它们并根据它们进行了一些测试。它没有用。我已经用新的堆栈跟踪编辑了这个问题。感谢您的帮助。
  • 等一下,我会安装 py3 并测试它。您已经检查了 jpeg 文件,不是吗?
  • 谢谢。我检查了 jpg 文件并与来自不同来源的其他几个文件进行了测试。 jpg文件没有任何作用。不过 GIF 有效。
  • 是的,我知道文档的那一部分,但是他们对 JPEG 文件的建议是我一开始就想做的,但它不起作用(尽管我得到的错误case 很奇怪:没有堆栈跟踪,只是一个脏的退出代码)。
  • 这里需要使用[PIL][1]或[pillow][2]。对不起,我似乎没有仔细阅读你的问题。 [1]:pypi.python.org/pypi/PIL [2]:pypi.python.org/pypi/Pillow
【解决方案3】:

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

i_tk = tkinter.PhotoImage(i)

【讨论】:

  • 感谢您的建议。我已经更新了这个问题,因为这个问题似乎已经被推到了更远的地方。
猜你喜欢
  • 1970-01-01
  • 2011-09-03
  • 2017-12-02
  • 1970-01-01
  • 1970-01-01
  • 2015-03-26
  • 2018-01-10
  • 2017-07-21
  • 2013-01-22
相关资源
最近更新 更多