【问题标题】:How to open PIL Image in Tkinter on Canvas如何在 Canvas 上的 Tkinter 中打开 PIL 图像
【发布时间】:2013-08-24 13:31:21
【问题描述】:

我似乎无法让我的 PIL 图像在画布上工作。代码:

from Tkinter import*
import Image, ImageTk
root = Tk()
root.geometry('1000x1000')
canvas = Canvas(root,width=999,height=999)
canvas.pack()
image = ImageTk.PhotoImage("ball.gif")
imagesprite = canvas.create_image(400,400,image=image)
root.mainloop()

错误:

Traceback (most recent call last):
  File "C:/Users/Mark Malkin/Desktop/3d Graphics Testing/afdds.py", line 7, in <module>
    image = ImageTk.PhotoImage("ball.gif")
  File "C:\Python27\lib\site-packages\PIL\ImageTk.py", line 109, in __init__
    mode = Image.getmodebase(mode)
  File "C:\Python27\lib\site-packages\PIL\Image.py", line 245, in getmodebase
    return ImageMode.getmode(mode).basemode
  File "C:\Python27\lib\site-packages\PIL\ImageMode.py", line 50, in getmode
    return _modes[mode]
KeyError: 'ball.gif'

我需要使用 PIL 图像而不是 PhotoImages,因为我想调整图像大小。请不要因为我想使用 Tkinter 而建议切换到 Pygame。

【问题讨论】:

  • 我很困惑——你说你不想使用PhotoImages,但你的代码使用了PhotoImage。您的意思是要使用ImageTk.PhotoImage 而不是Tkinter.PhotoImage
  • 您是否尝试过阅读PhotoImage 的文档?它需要一个图像对象,或者一个模式和一个大小。你也没有通过它;你正在传递一个文件名。 (return _modes[mode] 上的 KeyError 非常明显地表明它正在尝试将文件名视为一种模式……但不管它尝试了哪个模式,它都会失败。)

标签: python tkinter python-imaging-library tkinter-canvas


【解决方案1】:

我在这个问题上头撞墙了一段时间,直到我发现以下内容:

http://effbot.org/pyfaq/why-do-my-tkinter-images-not-appear.htm

显然,Python 的垃圾收集器可以丢弃 ImageTk 对象。我想使用很多小部件(比如我的)的应用程序更容易受到这种行为的影响。

【讨论】:

    【解决方案2】:

    (一个老问题,但到目前为止的答案只完成了一半。)

    阅读文档:

    class PIL.ImageTk.PhotoImage(image=None, size=None, **kw)
    
    • image – PIL 图像或模式字符串。 [...]
    • file – 从中加载图像的文件名(使用 Image.open(file))。

    所以在你的例子中,使用

    image = ImageTk.PhotoImage(file="ball.gif")
    

    或明确

    image = ImageTk.PhotoImage(Image("ball.gif"))
    

    (记住——正如你所做的那样:在你的 Python 程序中保留对图像对象的引用,否则在你看到它之前它就被垃圾收集了。)

    【讨论】:

      【解决方案3】:

      您可以导入多种图像格式,并使用此代码调整大小。 "basewidth" 设置图像的宽度。

      from Tkinter import *
      import PIL
      from PIL import ImageTk, Image
      
      root=Tk()
      image = Image.open("/path/to/your/image.jpg")
      canvas=Canvas(root, height=200, width=200)
      basewidth = 150
      wpercent = (basewidth / float(image.size[0]))
      hsize = int((float(image.size[1]) * float(wpercent)))
      image = image.resize((basewidth, hsize), PIL.Image.ANTIALIAS)
      photo = ImageTk.PhotoImage(image)
      item4 = canvas.create_image(100, 80, image=photo)
      
      canvas.pack(side = TOP, expand=True, fill=BOTH)
      root.mainloop()
      

      【讨论】:

        【解决方案4】:

        尝试先创建一个 PIL Image,然后使用它来创建 PhotoImage。

        from Tkinter import *
        import Image, ImageTk
        root = Tk()
        root.geometry('1000x1000')
        canvas = Canvas(root,width=999,height=999)
        canvas.pack()
        pilImage = Image.open("ball.gif")
        image = ImageTk.PhotoImage(pilImage)
        imagesprite = canvas.create_image(400,400,image=image)
        root.mainloop()
        

        【讨论】:

        • ImageTk.PhotoImage 是我想使用的,因为我希望能够调整大小。
        • raise ImportError("The _imaging C module is not installed") ImportError: The _imaging C module is not installed
        • @user164814 啊,那你就玩得很开心。您缺少 PIL 二进制文件 - 这是您的 PIL 安装问题,而不是代码问题。见this article。如果您使用 MacPorts 安装 PIL,请尝试自己安装系统构建。祝你好运。
        • @Brionius,如何保存这张图片?
        • @Mulagala 你应该打开一个新问题来获得答案。
        猜你喜欢
        • 2020-01-28
        • 2011-06-18
        • 1970-01-01
        • 2020-04-19
        • 1970-01-01
        • 2022-06-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多