Tkinter画布多次创建图像

时间:2018-11-16 20:45:38

标签: python canvas tkinter tkinter-canvas

我在代码中使用此功能在画布上创建图像:

def _create_image(self, coord):
    (x,y) = coord 
    self.one = ImageTk.PhotoImage(Image.open("test.jpg"))
    root.one = self.one
    self.canvas.create_image(x-25, y-25, image=self.one, anchor='nw', tags="image")

我的问题是,每次调用此函数时,都会删除旧图像并创建一个新图像。

如何防止删除旧图像?我想在画布上多次创建图像。

4 个答案:

答案 0 :(得分:1)

首先在例如__init__()中创建一个列表。

self.img_ref = []

然后在创建新图像时将它们添加到此列表中:

def _create_image(self, coord):
    (x,y) = coord 
    self.one = ImageTk.PhotoImage(Image.open("test.jpg"))
    root.one = self.one
    self.canvas.create_image(x-25, y-25, image=self.one,
                             anchor='nw', tags="image")
    self.img_ref.append(self.one)  # Keep reference to image

即使每张图像都是同一张图像,您也必须保留对其的引用。

答案 1 :(得分:1)

不需要,因为它始终是相同的图像文件,因此无需修改__init__()方法或存储引用列表。此处避免使用不必要的资源,因此将使用较少的内存(并且可能也会更快)。

它通过测试看看one属性是否已经存在来完成此操作,如果不存在,则仅读取图像数据并第一次创建PImageTk.PhotoImagehotoImage

这种方法允许您从同一Canvas创建多个ImageTk.PhotoImage小部件图像对象,而不是将其多个副本加载到内存中。

def _create_image(self, coord):
    (x,y) = coord

    if not getattr(self, 'one', None):  # First call?
        pil_img = Image.open("test.jpg")
        self.one = ImageTk.PhotoImage(pil_img)

    self.canvas.create_image(x-25, y-25, image=self.one,
                             anchor='nw', tags="image")

您还可以在一行中全部创建ImageTk.PhotoImage

    # pil_img = Image.open("test.jpg")  # Leave out.
    self.one = ImageTk.PhotoImage(file="test.jpg")

答案 2 :(得分:0)

Image.open()每次都会重写图像。

答案 3 :(得分:0)

感谢 Martineau 对这一问题的投入。 ImageTk 变量如果保持独立且不重复使用,则似乎可以工作。否则,即使是新实例,它们也会保持相同的文件路径。通过保留 ImageTk 的单独变量,我设法将多个不同的图像绘制到画布上

    from PIL import Image, ImageTk
    import tkinter as tk
    from tkinter.filedialog import askopenfilename


    root = tk.Tk 
    root.mainloop()

    self.ph = [] #keep photoimage instances separate
    
    def appendImages(self):  #Call appendImages as many times as needed
        path = askopenfilename(initialdir="/", title="Select file",  filetypes(("all files", "*.*"),("jpeg files", ".jpg")))
        im = Image.open(path)
        self.ph.append(ImageTk.PhotoImage(im))
        self.canvasImage=self.canvas.create_image(x,y,anchor=NW,image=self.ph[len(self.ph)-1])

最后一行绘制用户最近选择的图像