Python 如何显示通过filedialog选择的图像(在画布上)?

Python 如何显示通过filedialog选择的图像(在画布上)?,python,tkinter,python-imaging-library,tkinter-canvas,Python,Tkinter,Python Imaging Library,Tkinter Canvas,几天前我开始了一个项目,但不幸的是我被卡住了。我想做一个图像编辑器(一个非常简单的编辑器;D),在这里,我可以使用filedialog选择一个图像,然后我就可以进行一些修改,比如旋转。我的问题是,我可以选择图像,但一旦我选择了,我就不能在画布上显示图像 它说:“名称‘图像’不可定义” 我想我的问题是程序想要在画布上显示图像,但我还没有选择它 from tkinter import * from PIL import Image, ImageTk from tkinter import filed

几天前我开始了一个项目,但不幸的是我被卡住了。我想做一个图像编辑器(一个非常简单的编辑器;D),在这里,我可以使用filedialog选择一个图像,然后我就可以进行一些修改,比如旋转。我的问题是,我可以选择图像,但一旦我选择了,我就不能在画布上显示图像

它说:“名称‘图像’不可定义”

我想我的问题是程序想要在画布上显示图像,但我还没有选择它

from tkinter import *
from PIL import Image, ImageTk
from tkinter import filedialog

root = Tk()

#function to select my image by using the filedialog
def select_image(): 
    file_path = filedialog.askopenfilename()
    image = Image.open(file_path)

#button to press to open filedialog
select = Button(root, text="select an image", command=select_image)
select.pack()

#the canvas where the image will be display
canvas = Canvas(root, width= 100, height=100, bg="grey")
canvas.pack()

image_tk = ImageTk.PhotoImage(image)
canvas.create_image(0,0, image= image_tk)


root.mainloop()

这里有几个问题:

  • 你永远不会调用你的函数!你的代码忽略了
    定义图像后选择图像()

  • 变量
    image
    仅在(未调用的)函数中定义,因此当您试图通过
    ImageTk.PhotoImage()
    使用它时,它是 未定义

  • 尝试以下方式返回图像对象:

    from tkinter import *
    from PIL import Image, ImageTk
    from tkinter import filedialog
    
    root = Tk()
    
    #function to select my image by using the filedialog
    def select_image(): 
        file_path = filedialog.askopenfilename()
        return Image.open(file_path)
    
    #button to press to open filedialog
    select = Button(root, text="select an image", command=select_image)
    select.pack()
    
    #the canvas where the image will be display
    canvas = Canvas(root, width= 100, height=100, bg="grey")
    canvas.pack()
    
    image_tk = ImageTk.PhotoImage(select_image())
    canvas.create_image(0,0, image= image_tk)
    
    
    root.mainloop()
    

    请注意,您并没有在select_image()函数中检查错误或取消。您最好也在函数中处理取消或错误

    在有图像文件显示之前,可以创建图像对象,但不能以您正在执行的方式。您只需创建一个空图像对象并跟踪图像对象id,然后在
    选择\u image
    中重新配置该对象

    例如,不要在主程序中定义
    image\u tk
    。将在画布上创建图像项的行更改为:

    image_id = canvas.create_image(0,0, anchor="nw")
    
    (注意:如果没有
    锚定
    选项,图像的中心将位于0,0。我猜您希望图像的左上角位于0,0)

    接下来,在
    select\u image
    中,您将完成获取图像、保存对图像的引用(以避免函数返回时删除图像)以及在画布中显示图像的所有工作。它看起来像这样:

    def select_image(): 
        # ask the user for the filename
        file_path = filedialog.askopenfilename()
    
        # only show the image if they chose something
        if file_path:
            # open the file
            image = Image.open(file_path)
    
            # create the image object, and save it so that it
            # won't get deleted by the garbage collector
            canvas.image_tk = ImageTk.PhotoImage(image)
    
            # configure the canvas item to use this image
            canvas.itemconfigure(image_id, image=canvas.image_tk)
    

    两个问题:一,。实际上,您并没有从代码主体中调用函数select_image(),以及2。您第一次在该函数中设置了“image”(从未调用),因此当您到达底部时,image仍然未定义。我会重构你的代码,从你的函数中返回图像对象。谢谢你,现在效果好多了!但是当我启动程序时,文件对话框会自动打开。有没有办法只在按下按钮时打开文件对话框?是的,请看这个问题:。出于礼貌,如果你能投赞成票或接受我的回答,那就太好了,因为我花了一些时间在这个问题上。这就是这个网站鼓励人们互相帮助的方式。:-)你的第一句话似乎不正确
    select\u image
    不会被忽略,因为它是在用户单击按钮时调用的。另外,在调用mainloop之前打开一个对话框通常是个坏主意。它有时会在某些平台上工作,但会在Windows上引起问题。