绘制矩形Tkinter时逻辑填充颜色

时间:2020-04-03 07:49:46

标签: python tkinter python-imaging-library drawrectangle

使用PIL在画布上的图像上绘制矩形。我希望根据画布中图像的像素颜色更改填充矩形。

我已经引用了一个交叉贴(下面粘贴了链接)来在Tkinter中创建带有鼠标事件的矩形。

create_rectangle用鼠标事件指定的颜色填充矩形(示例:在此示例中,矩形填充为黑色)。有没有一种方法可以根据背景图像的现有像素颜色在逻辑上更改填充颜色?我的意思是,在绘制矩形时,我只需要将背景图像的白色像素变成红色,其余的则用不同的颜色即可。

Drawing rectangle using mouse events in Tkinter

enter image description here

[1]: https://i.stack.imgur.com/W41kX.jpg

def rec_on_button_press(self,event):
    self.start_x = event.x
    self.start_y = event.y
    self.rect=self.image_canvas.create_rectangle(self.x, self.y, 1, 1,fill=self.python_red)
def rec_on_move(self, event):
    curX, curY = (event.x, event.y)
    imagenp= np.array(image)
    if imagenp[curY,curX]==255:
        self.python_red="#EE204D"
    else:
        self.python_red=None
    self.image_canvas.coords(self.rect, self.start_x, self.start_y, curX, curY)

def rec_on_button_release(self, event):
    pass

2 个答案:

答案 0 :(得分:1)

原理: 裁剪选择的图像,创建并显示。

需要修改代码,完整代码示例(示例将255(白色)转换为0(黑色)):

import tkinter as tk # this is in python 3.4. For python 2.x import Tkinter
from PIL import Image, ImageTk
import numpy as np
import ctypes
ctypes.windll.shcore.SetProcessDpiAwareness(2) # for windows 10

class ExampleApp(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.x = self.y = 0
        self.canvas = tk.Canvas(self, width=512, height=512, cursor="cross")
        self.canvas.pack(side="top", fill="both", expand=True)
        self.canvas.bind("<ButtonPress-1>", self.on_button_press)
        self.canvas.bind("<B1-Motion>", self.on_move_press)
        self.canvas.bind("<ButtonRelease-1>", self.on_button_release)

        self.rect = None

        self.start_x = None
        self.start_y = None
        self.python_red = None

        self.im = Image.open(r'ImagePath').convert("L")
        self.move_imageID = None
        self.move_image = None
        self.tk_im = ImageTk.PhotoImage(self.im)
        self.canvas.create_image(0,0,anchor="nw",image=self.tk_im)



    def on_button_press(self, event):
        # save mouse drag start position
        self.start_x = event.x
        self.start_y = event.y
        self.rect = self.canvas.create_rectangle(self.x, self.y,  0, 0, outline="black")

    def on_move_press(self, event):
        self.canvas.delete(self.move_imageID)
        crop_image = self.im.crop((self.start_x,self.start_y,event.x,event.y))
        imageArray = np.array(crop_image)
        if imageArray.shape:
            for i in range(imageArray.shape[0]):
                for j in range(imageArray.shape[1]): # convert  the white pixel to black
                    if imageArray[i,j] == 255:
                        imageArray[i,j] = 0
            self.move_image = Image.fromarray(imageArray)
            self.move_image = ImageTk.PhotoImage(self.move_image)
            self.move_imageID = self.canvas.create_image(self.start_x,self.start_y,anchor="nw",image=self.move_image)
            self.canvas.coords(self.rect,self.start_x,self.start_y,event.x,event.y)
            self.canvas.lift(self.rect)

    def on_button_release(self, event):
        pass


if __name__ == "__main__":
    app = ExampleApp()
    app.mainloop()

现在:

enter image description here

选择区域:

enter image description here

答案 1 :(得分:0)

原理:将图像转换为numpy数组,并使用opencv绘制矩形。处理像素颜色后,将其转换回图像。

def rec_on_button_press(self,event):
        self.start_x = event.x
        self.start_y = event.y
        self.rect=self.image_canvas.create_rectangle(self.x, self.y, 1, 1,fill=self.python_red)
def rec_on_move(self, event):
        curX, curY = (event.x, event.y)
        cropimage=originalimage.crop((self.start_x,self.start_y,curX,curY))
        cropimagergb=cropimage.convert('RGB')
        cropimagergb.save('crop1.png')
        imagergbcv2=cv2.imread('crop1.png')
        if imagergbcv2.shape[:2]:
            for i in range(imagergbcv2.shape[0]):
                for j in range(imagergbcv2.shape[1]): 
                    color=imagergbcv2[i,j]
                    if (color[0]==255 and color[1]==255 and color[2]==255):
                        imagergbcv2[i,j]=(0,255,0)
        cv2.imwrite('crop2.png',imagergbcv2)
        croppedimage=cv2.imread('crop2.png')
        originalimage[self.start_y:self.start_y+croppedimage.shape[0],self.start_x:self.start_x+croppedimage.shape[1]]=croppedimage
        cv2.imwrite('originalpluscropped.png',originalimage)
    self.image_canvas.coords(self.rect, self.start_x, self.start_y, curX, curY)

def rec_on_button_release(self, event):
    pass
    self.image=Image.open('originalpluscropped.png')