0

I have an image in a canvas. The user can draw a rectangle on this image and the image becomes cropped and resized. Here is my code:

self._root = tk.Tk()
self._rect = None
image_cv2 = cv2.imread(path_image)
self._root.minsize(height=image_cv2.shape[0], width=image_cv2.shape[1] + 150)
self._root.title("Image")
image = cv2.cvtColor(image_cv2, cv2.COLOR_BGR2RGB)
image2 = Image.fromarray(image)
image = ImageTk.PhotoImage(image2)
canvas_2 = tk.Canvas( self._root, height=image_cv2.shape[0], width=image_cv2.shape[1])
canvas_2.grid(row=0, column=1)
canvas_2.image = image
self._image_can2 = canvas_2.create_image(0, 0, anchor='nw', image=image)
canvas_2.bind("<Button-1>", lambda event: self.__on_button_press__(event, canvas_2))
canvas_2.bind("<B1-Motion>", lambda event: self.__on_move_press__(event, canvas_2))
canvas_2.bind("<ButtonRelease-1>", lambda event: self.__on_button_release__(event, canvas_2, image2))




def __on_button_press__(self, event, canvas_img):
    # save mouse drag start position and display a _rectangle
    if self._rect is not None:
        canvas_img.delete(self._rect)
    self._start_x = event.x
    self._start_y = event.y
    self._rect = canvas_img.create_rectangle(self._start_x, self._start_y, self._start_x + 1, self._start_y + 1, fill="", outline="green", width=5)

def __on_move_press__(self, event, canvas_img):
    # expand rectangle as you drag the mouse
    curX = event.x
    curY = event.y
    canvas_img.coords(self._rect, self._start_x, self._start_y, curX, curY)
    return True

def __on_button_release__(self, event, canvas_img, image):
    # save mouse drag ststopart position and display a rectangle
    if self._rect is not None:
        if self._start_x > event.x or self._start_y > event.y:
            canvas_img.delete(self._rect)
            messagebox.showwarning('Error', 'You have to draw the rectangle from the top-left to the bottom-right')
        self._stop_x = event.x
        self._stop_y = event.y
        self.__cropped_img__(canvas_img, image)
    return True

def __cropped_img__(self, canvas_img, image):
    # cropped the image according to the drawn rectangle
    canvas_img.delete(self._rect)
    image = image.crop([self._start_x, self._start_y, self._stop_x, self._stop_y]).resize((500, 500))
    image = ImageTk.PhotoImage(image)
    canvas_img.itemconfig(self._image_can2, image=image)
    return True

The rectangle is drawn, but the itemconfig doesn't work: the image disappears. When at the end of the function cropped_img instead of return True, I put something wrong like return true, I got an error : Exception in Tkinter callback [...] NameError: name 'true' is not defined

BUT the image is cropped and resized. I don't understand why it doesn't work when there is no error.

According to this link: Why does Tkinter image not show up if created in a function?, I've tried to put

global image

at the beginning of my code, I got the same error.

Lydie Garsia
  • 71
  • 1
  • 8

0 Answers0