python 如何使用tkinter在PIL图像上单击来绘制像素

ffx8fchx  于 2023-09-29  发布在  Python
关注(0)|答案(1)|浏览(125)

我试图画一个像素的PIL图像上点击,我使用Tkinter显示图像,我可以得到坐标的点击像素已经,但我不能显示在屏幕上画的像素
这是tkinter类,我在其中显示PIL图像

class selectPoints(tk.Frame):
    def __init__(self, master):
    tk.Frame.__init__(self, master)
    alto = int(master.alto)
    ancho = int(master.ancho)
    master.geometry(f'{ancho+50}x{alto+100}')
    canva = Image.new('RGB', (ancho, alto), (255, 255, 255))

                # This is the function where i get the click coordinates        
        def callback(event): 
            color = (0, 255, 0)
            canva.putpixel((event.x, event.y), color)
            print ("clicked at: ", event.x, event.y)
        
    tkpic = ImageTk.PhotoImage(canva)
    label = tk.Label(self, image=tkpic)
    label.image = tkpic  # Save reference to image
    label.pack()
    label.bind("<Button-1>", callback)

这是图像的外观,以及控制台上单击的坐标:Tkinter windowConsole output
我尝试在每次单击时重新应用Tkinter窗口上的图像,但图像保持原始状态,没有任何变化

def callback(event):
    color = (0, 255, 0)
    canva.putpixel((event.x, event.y), color)

    tkpic = ImageTk.PhotoImage(canva)
    label = tk.Label(self, image=tkpic)
    label.image = tkpic  # Save reference to image
    
    print ("clicked at: ", event.x, event.y)
2fjabf4q

2fjabf4q1#

您不应该创建图像的新示例。创建图像一次,然后对其进行修改。更改将自动显示在窗口中。
而且,看起来你不需要使用PIL。标准的tk.PhotoImage类能够更改现有图像的单个像素。使用它将降低代码的复杂性。
您可能仍然希望或需要使用PIL来调整图像大小或将其保存为tkinter不支持的格式,但我的建议是只在需要使用PIL的地方使用PIL,并在可能的情况下使用内置功能。
这里有一个小例子,展示了如何创建一次图像,然后在图像上使用put方法修改它。此示例还演示了如何填充整个区域,方法是调用put,首先用黑色填充整个图像。也可以用颜色数组填充一个区域(即:来模拟不同的画笔形状),但为了使示例简单,我不会在这里展示如何做到这一点。

import tkinter as tk

class Drawable(tk.Label):
    def __init__(self, parent, width=100, height=100):
        super().__init__(parent)
        self._image = tk.PhotoImage(master=self, width=width, height=height)
        self.configure(image=self._image)
        self._image.put("#000000", to=(0,0,99,99))

        self.bind("<1>", self._click_callback)

    def _click_callback(self, event):
        color = "#%02x%02x%02x" % (0, 255, 0)
        self._image.put(color, to=(event.x, event.y))

root = tk.Tk()
draw = Drawable(root, 100, 100)
draw.configure(bd=2, relief="groove")
draw.pack(padx=20, pady=20)
tk.mainloop()

随机点击十几次后的示例截图:

相关问题