'how to drawing in python tkinter.canvas video stream
I've been trying to solve a problem for days.
It's about a function:
a video stream is loaded and displayed in a python tkinter.canvas. that's ok - but I have a paint function to draw on the video stream.
How can I make the drawing stay permanent?
# Wiederholung
def update(self):
ret, frame = self.vid.get_frame()
# Bildfolge neu anzeigen
if ret:
self.photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(frame))
self.image = self.canvas.create_image(0, 0, image = self.photo, anchor = tkinter.NW)
# Logo einblenden
self.overlay_img = tkinter.PhotoImage(file = "logo.png")
self.canvas.tag_raise( self.overlay_img)
self.canvas.create_image(width -160 , 5, image=self.overlay_img, anchor=tkinter.NW)
self.window.after(self.delay, self.update)
def paint(self,event):
global count
if count == 10:
count = 0
count += 1
dot_color = "yellow" #"red"
x1, y1 = ( event.x - 10 ), ( event.y - 10 )
x2, y2 = ( event.x + 10 ), ( event.y + 10 )
self.canvas.create_oval( x1, y1, x2, y2, fill = dot_color)
self.canvas.create_text(x1+10, y1+10, text=str(count))
The paint function in tkinter.vanvas is linked to the mouse click. how is the drawn circle retained in the running stream?
RPI 4, Python 3.7
Sorry for my English, I'm from Germany
Solution 1:[1]
You should not create new image items (logo and video frame) in each iteration since the new image item will have higher z-order than other created items in the canvas.
Create the image items once in __init__() instead and update the video frame inside update() which does not change the z-order of the image item:
def __init__(self, ...):
...
# image item for the video frame
self.image = self.canvas.create_image(0, 0, image=None, anchor = tkinter.NW)
# Logo
self.overlay_img = tkinter.PhotoImage(file="logo.png")
self.canvas.create_image(width-160 , 5, image=self.overlay_img, anchor=tkinter.NW)
...
def update(self):
ret, frame = self.vid.get_frame()
# Bildfolge neu anzeigen
if ret:
# update video frame
self.photo = PIL.ImageTk.PhotoImage(image=PIL.Image.fromarray(frame))
self.canvas.itemconfigure(self.image, image=self.photo)
self.window.after(self.delay, self.update)
Solution 2:[2]
Well the problem appears to be here is the oval and the text are there, but hidden beneath the frame image. All you needs to do is bring those to front.
canvas.tag_raise method can be a solution for this situation.
In below example, for each canvas item a tag is assigned. You can assign multiple tags as well, if required. The method bring_to_front is being called after every frame update which is using tag_raise function to bring the canvas items with the given tags on the top.
self.paint_oval_tag = "paint_oval_tag"
self.paint_text_tag = "paint_text_tag"
self.frame_logo_tag = "frame_logo_tag"
self.frame_image_tag = "frame_image_tag"
def update(self):
ret, frame = self.vid.get_frame()
# Bildfolge neu anzeigen
if ret:
# delete the existing image form the canvas,
# otherwise, it will run out of memorysoon
self.canvas.delete(self.frame_image_tag)
self.photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(frame))
self.image = self.canvas.create_image(0, 0, image = self.photo, anchor = tkinter.NW, tags=self.frame_image_tag)
# call this method to bring other items to font
self.bring_to_front()
self.window.after(self.delay, self.update)
def bring_to_front(self):
self.canvas.tag_raise(self.frame_logo_tag)
self.canvas.tag_raise(self.paint_oval_tag)
self.canvas.tag_raise(self.paint_text_tag)
# Call this method after creating the canvas
def show_logo(self):
# Logo einblenden
self.overlay_img = tkinter.PhotoImage(file = "logo.png")
self.canvas.create_image(width -160 , 5, image=self.overlay_img, anchor=tkinter.NW, tags=self.frame_logo_tag)
def paint(self,event):
global count
if count == 10:
count = 0
count += 1
dot_color = "yellow" #"red"
x1, y1 = ( event.x - 10 ), ( event.y - 10 )
x2, y2 = ( event.x + 10 ), ( event.y + 10 )
self.canvas.create_oval( x1, y1, x2, y2, fill = dot_color, tags=self.paint_oval_tag)
self.canvas.create_text(x1+10, y1+10, text=str(count), tags=self.paint_text_tag)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | acw1668 |
| Solution 2 | Meritor |
