I am trying to draw text on Image where the user clicks.
Getting this error:
Exception in Tkinter callback
Traceback (most recent call last):File "C:\Users\Admin\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 1705, in __call__return self.func(*args)File "C:/Users/Admin/PycharmProjects/ashish/td.py", line 35, in draw_textcv2.putText(img, "OpenCV + Jurassic Park!!!", (event.x,event.y), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
TypeError: Expected cv::UMat for argument 'img'
if __name__ == "__main__":root = Tk()frame = Frame(root, bd=2, relief=SUNKEN)canvas = Canvas(frame, bd=0)canvas.grid(row=0, column=0, sticky=N+S+E+W)frame.pack(fill=BOTH,expand=1)#adding the imageFile = filedialog.askopenfilename(parent=root, initialdir="F:/",title='Choose an image.')img = ImageTk.PhotoImage(Image.open(File))canvas.create_image(0,0,image=img,anchor="nw")#function to be called when mouse is clickeddef draw_text(event):cv2.putText(img, "OpenCV + Jurassic Park!!!", (event.x,event.y), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)cv2.imshow("Text", img)#mouseclick eventcanvas.bind("<Button 1>",draw_text)root.mainloop()
Your img
is ImageTK
object from tkinter
but cv2
is not part of tkinter
and cv2.putText
doesn't work with ImageTK
. It needs something different. cv2
has own function to read image and it creates object which you can use with cv2.putText()
.
But canvas
has function to display text on top of image and you don't need cv2
. But it can't be saved in file as image with text.
But Image
has function to draw text on image and it can be saved in file.
So finally you don't need cv2
.
I use Image.Draw
to create object on which I can put text or draw line/square/etc.
After adding text I replace image on canvas.
This method create image with text which you can save in file (img.save()
)
from tkinter import *
from tkinter import filedialog
from PIL import Image, ImageTk, ImageDraw# function to be called when mouse is clicked
def draw_text(event):global imgtkglobal cv_img# create object for drawingdraw = ImageDraw.Draw(img)# put textdraw.text((event.x,event.y), "ImageDraw + Jurassic Park!!!")# replace old imagecanvas.delete(cv_img_id) imgtk = ImageTk.PhotoImage(img)cv_img_id = canvas.create_image(0, 0, image=imgtk, anchor="nw")if __name__ == "__main__":root = Tk()frame = Frame(root, bd=2, relief=SUNKEN)frame.pack(fill=BOTH, expand=1)canvas = Canvas(frame, bd=0)canvas.grid(row=0, column=0, sticky=N+S+E+W)#adding the imagefile = filedialog.askopenfilename(parent=root, initialdir="F:/",title='Choose an image.')img = Image.open(file)imgtk = ImageTk.PhotoImage(img)cv_img_id = canvas.create_image(0, 0, image=imgtk, anchor="nw")#mouseclick eventcanvas.bind("<Button 1>", draw_text)root.mainloop()
Using canvas.create_text
you can put text on top of image which you can move/remove later but it doesn't create image with text which you can save in file.
from tkinter import *
from tkinter import filedialog
from PIL import Image, ImageTk# function to be called when mouse is clicked
def draw_text(event):canvas.create_text((event.x,event.y), text="Canvas + Jurassic Park!!!")if __name__ == "__main__":root = Tk()frame = Frame(root, bd=2, relief=SUNKEN)frame.pack(fill=BOTH, expand=1)canvas = Canvas(frame, bd=0)canvas.grid(row=0, column=0, sticky=N+S+E+W)#adding the imagefile = filedialog.askopenfilename(parent=root, initialdir="F:/",title='Choose an image.')imgtk = ImageTk.PhotoImage(Image.open(file))canvas.create_image(0, 0, image=imgtk, anchor="nw")#mouseclick eventcanvas.bind("<Button 1>", draw_text)root.mainloop()