【问题标题】:Tkinter.PhotoImage doesn't not support png imageTkinter.PhotoImage 不支持 png 图像
【发布时间】:2015-02-20 08:28:14
【问题描述】:

我正在使用 Tkinter 编写 GUI,并希望在 Tkiner.Label 中显示 png 文件。 所以我有一些这样的代码:

self.vcode.img = PhotoImage(data=open('test.png').read(), format='png')
self.vcode.config(image=self.vcode.img)

此代码在我的 Linux 机器上正确运行。但是当我在我的 Windows 机器上运行它时,它失败了。我也在其他几台机器(包括windows和linux)上测试过,一直失败。

回溯是:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python27\lib\lib-tk\Tkinter.py", line 1486, in __call__
    return self.func(*args)
  File "C:\Documents and Settings\St\client\GUI.py", line 150, in showrbox
    SignupBox(self, self.server)
  File "C:\Documents and Settings\St\client\GUI.py", line 197, in __init__
    self.refresh_vcode()
  File "C:\Documents and Settings\St\client\GUI.py", line 203, in refresh_vcode
    self.vcode.img = PhotoImage(data=open('test.png').read(), format='png')
  File "C:\Python27\lib\lib-tk\Tkinter.py", line 3323, in __init__
    Image.__init__(self, 'photo', name, cnf, master, **kw)
  File "C:\Python27\lib\lib-tk\Tkinter.py", line 3279, in __init__
   self.tk.call(('image', 'create', imgtype, name,) + options)
TclError: image format "png" is not supported

如果我在源代码中删除format='png',那么traceback会变成:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python27\lib\lib-tk\Tkinter.py", line 1486, in __call__
    return self.func(*args)
  File "C:\Documents and Settings\St\client\GUI.py", line 150, in showrbox
    SignupBox(self, self.server)
  File "C:\Documents and Settings\St\client\GUI.py", line 197, in __init__
    self.refresh_vcode()
  File "C:\Documents and Settings\St\client\GUI.py", line 203, in refresh_vcode
    self.vcode.img = PhotoImage(data=open('test.png').read())
  File "C:\Python27\lib\lib-tk\Tkinter.py", line 3323, in __init__
    Image.__init__(self, 'photo', name, cnf, master, **kw)
  File "C:\Python27\lib\lib-tk\Tkinter.py", line 3279, in __init__
    self.tk.call(('image', 'create', imgtype, name,) + options)
TclError: couldn't recognize image data

那么,我应该怎么做才能让它支持 png 文件呢?

【问题讨论】:

  • 您是否尝试过使用不同的文件格式?参见例如here.
  • @jonrsharpe,是的,我尝试过 'gif' 格式,它在我的 linux 机器上显示图像,但在我的 windows 机器上显示黑色(或白色或一些噪音)区域。
  • 你用什么来转换图片的?它是否在Tk 应用程序外部的所有计算机上正确显示?
  • @jonrsharpe,我没有使用任何东西来转换图像,它只是从互联网下载的图像。当然我测试了其他几个图像,都失败了。图像可以在Tk 应用程序外正确显示(在 windows 上使用“windows image andfax viewer”或在 linux 上使用“feh”)。
  • 所以你只是告诉 tkinter 这是一个 gif 而它实际上仍然是一个 png?为什么你认为这会起作用?! 转换它。

标签: python linux tkinter tk


【解决方案1】:

PIL 现在替换为 Pillow http://pillow.readthedocs.io/en/3.2.x/

解决方案:

from Tkinter import *
import PIL.Image
import PIL.ImageTk

root = Toplevel()

im = PIL.Image.open("photo.png")
photo = PIL.ImageTk.PhotoImage(im)

label = Label(root, image=photo)
label.image = photo  # keep a reference!
label.pack()

root.mainloop()

如果在代码中找不到PIL,则需要安装pillow

pip install pillow

【讨论】:

  • 这个问题不涉及PIL的使用,所以不清楚你认为这与这个问题有什么关系。
  • 我不明白。您想完全重写 PIL 以使其可用吗?我只是提供了一个最简单的解决方案。
  • 这个问题没有问任何关于 PIL 或 Pillow 的内容,但您的陈述是“PIL 被 Pillow 取代”。如果我是 OP,我会说“好吧,这有什么关系?”我认为如果您将开头的段落改写为“Tkinter 不支持 png,您需要使用 Pillow 创建 Tkinter 识别的图像”,答案会更好。当问题没有提到 PIL 或 Pillow 时,只是说“PIL 被 Pillow 取代”令人困惑。您必须记住,您正在为对 tkinter、PIL 或 Pillow 几乎一无所知的人写答案。
  • 你是对的,我正在考虑选择的答案。
  • Pillow 5.1 和 python 3.5,导入必须更改为 from PIL import Image, ImageTk
【解决方案2】:

tkinter 仅支持 3 种文件格式,即 GIF、PGM 和 PPM。您要么需要将文件转换为 .GIF 然后加载它们(要容易得多,但正如 jonrsharpe 所说,如果不先转换文件,什么都不会起作用),或者您可以将程序移植到 Python 2.7 并使用 Python Imaging Library (PIL)及其 tkinter 扩展以使用 PNG 图像。

您可能会发现有用的链接:http://effbot.org/tkinterbook/photoimage.htm

【讨论】:

  • 谢谢。我很抱歉我没有清楚地表达自己。我的意思是我尝试使用另一个 gif 图像的“gif”格式,而不是“png”图像,它在我的 linux 机器上正确显示图像,但在我的 Windows 机器上显示黑色(或白色或嘈杂)区域,正如我所说琼夏普最后,我发现如果我使用self.vcode.img = PhotoImage(data=open('test.gif').read(), format='gif'),它会失败。但如果我使用self.vcode.img = PhotoImage(file='test.gif'),它可以正常工作
  • tk 8.6 支持.png。 Widows 3.4.z 安装程序在 *nix 上安装 tcl/tk 8.6.z,这取决于系统附带的内容以及用户升级到的内容。这就是为什么您的程序可以在一台机器上运行而在另一台机器上运行的原因。除非用户以某种方式升级,否则 OSX 将拥有 8.5.z。如果可能的话,OSX 的 PSF 3.5 安装程序将安装 8.6。
  • @TerryJanReedy 这对我来说是个新闻,但我很高兴听到这个消息。我会记住这一点以供将来参考。
  • @TerryJanReedy 感谢上帝,我阅读了您的评论,这可能为我节省了很多时间。
  • 更正:PSF 3.6(不是 3.5)安装程序有望安装 tk 8.6。对于 3.5,可以使用不同的安装程序,例如来自“Homebrew”的安装程序。我不在 OSX 上,也不知道备用 Python-Mac 安装程序的优缺点。
【解决方案3】:

Tkinter 8.6 支持 png 文件格式,而 tkinter 8.5 不支持。如果你有升级 python 的选项,你应该可以使用 png。 如果你必须使用旧版本的 python,你应该使用 Pillow (maintained pil fork),它也适用于 python3。

如果您正在开始一个新项目不要使用已接受答案中建议的 python2 或 PIL,它们都是已弃用的技术。

【讨论】:

    【解决方案4】:

    在 OS X 的官方 python.org 64 位(仅限)安装程序中已修复。Tk 版本 8.6 包含在开箱即用。警告:如果你使用自制软件,在这篇文章中,brew install python3 只会给你 8.5,而使用 png 需要 8.6,所以你必须使用官方安装程序。检查您使用的是哪个 Tk:

    $ python3 -c 'import tkinter; print(tkinter.TkVersion);'
    

    如果它报告 8.6,你就可以走了。

    【讨论】:

      【解决方案5】:
      from tkinter import *
      from tkinter import messagebox
      import os
      from PIL import Image, ImageTk
      
      
      root = Tk()
      root.geometry("1300x720")
      root.title("KEDİLERİMİZ ve KÖPEKLERİMİZ")
      class Ana:
          def __init__(self,name,roll):
              self.name = name
              self.roll = roll
      resim = Label(root,width=77,height=43,bg="blue")
      resim.place(x=730,y=10)
      o = "1.PNG"
      hu = o.find(".")
      mu = o[hu:]
      if mu == ".gif" or mu == ".png":
          img = PhotoImage(file = o)
      else:
          photo = Image.open(o)
          img = ImageTk.PhotoImage(photo)
      resim.configure(image=img,width=img.width(),height=img.height())
      resim.image = img
      

      【讨论】:

        【解决方案6】:

        在 Windows 上,您必须使用这种特定格式:

        Example = PhotoImage(file='photo.png')
        

        如果您希望将其调整为更小的尺寸:

        Example = Example.subsample(2, 2)
        

        Example = Example.subsample(3, 3)
        

        总代码:

        Example = PhotoImage(file='photo.png')
        Example = Example.subsample(1, 1)
        

        但未来警告,除非您将照片与脚本放在同一个文件中,否则您必须将文件位置与照片一起归档!

        【讨论】:

          【解决方案7】:

          尝试使用 PIL 库而不是将图像转换为 GIF、PGM 或 PPM (PhotoImage) 仅接受这 3 种格式。

          import tkinter as tk
          import PIL.Image
          import PIL.ImageTk
          
          base = tk.Tk()
          base.title("Dialy Dose")
          
          logoPath = r"C:\Users\saigopi\Downloads\logo.png"
          
          ref = PIL.Image.open(logoPath)
          photo = PIL.ImageTk.PhotoImage(im)
          
          inputEdit = tk.Label(base,text="Enter Quote")
          save = tk.Button(base,text="Save",background="green",command=save())
          logo = tk.Label(base,image=photo,text="Logo bro lite")
          quote = tk.Label(base,text="I am saying you are more than something")
          
          inputEdit.pack()
          save.pack()
          logo.pack()
          quote.pack()
          
          base.mainloop()
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-02-14
            • 2011-09-20
            • 1970-01-01
            • 1970-01-01
            • 2012-11-15
            • 1970-01-01
            相关资源
            最近更新 更多