如何在Tkinter的画布上打开PIL图像

9

我似乎无法在画布上使用我的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,因为我想调整我的图片大小。请不要建议切换到Pygame,因为我想使用Tkinter。


1
我有点困惑 - 你说你不想使用 PhotoImage,但是你的代码却使用了 PhotoImage。你的意思是想使用 ImageTk.PhotoImage 而不是 Tkinter.PhotoImage 吗? - Brionius
1
你尝试过阅读有关PhotoImage的文档吗?它需要一个图像对象或模式和大小。你没有传递任何一个;你传递了一个文件名。(在return _modes [mode]上的KeyError非常明显,它试图将文件名视为模式...但无论它尝试哪个,它都会失败。) - abarnert
4个回答

17

先尝试创建一个PIL图像,然后使用该图像来创建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是我想使用的,因为我想要能够改变大小。 - user164814
引发 ImportError("未安装 _imaging C 模块") ImportError: 未安装 _imaging C 模块 - user164814
@user164814 啊,那你会有一段愉快的时光。你缺少一个PIL二进制文件 - 这是你的PIL安装出了问题,而不是代码的问题。请参考这篇文章。如果你使用MacPorts安装PIL,请尝试自己安装系统构建。祝你好运。 - Brionius
@Brionius,如何保存这张图片? - Mulagala
@Mulagala,您应该开一个新的问题来获取答案。 - Brionius
使用 Image 是可以的,但这个答案只是半成品,请看下面我的回答。 - One

9

这是一个老问题,但目前的答案只有一半正确。

请阅读文档:

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程序中保留对图像对象的引用,否则它将在您看到它之前被垃圾回收。)

5
您可以使用以下代码导入多种图片格式,并进行调整大小。 "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()

3

在这个问题上,我曾经苦苦思索了一段时间,直到我找到了以下解决方法:

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

显然,Python的垃圾回收器可能会破坏ImageTk对象。我想使用大量小部件的应用程序(如我的应用)更容易受到这种行为的影响。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接