'How to draw on an image Tkinter canvas, PIL

I would want to be able to draw on an image being displayed by a tkinter canvas PIL. I tried google searching but all the results would be how to draw on an image without tkinter or how to display an image which is not what i want. I also would like it to be like live(color while i move my mouse). Is there any way to do this. If there are no ways with PIL is there a way with tkinter.

Answer

the answer from this post here if the link wont work here is the code:

from tkinter import *
from tkinter import ttk

class Sketchpad(Canvas):
    def __init__(self, parent, **kwargs):
        super().__init__(parent, **kwargs)
        self.bind("<Button-1>", self.save_posn)
        self.bind("<B1-Motion>", self.add_line)
        
    def save_posn(self, event):
        self.lastx, self.lasty = event.x, event.y

    def add_line(self, event):
        self.create_line((self.lastx, self.lasty, event.x, event.y), width=20, capstyle='round')
        self.save_posn(event)

root = Tk()
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)

sketch = Sketchpad(root)
sketch.grid(column=0, row=0, sticky=(N, W, E, S))

root.mainloop()


Solution 1:[1]

I think the best approach would be to do the drawing with tkinter because otherwise you will need to continually update the canvas widget every time the image gets changed by the PIL (which might be too slow and interfere with "live" drawing).

tkinter Canvases have several different vector and text drawing capabilities, and you can draw/display them on top of an image that's also being displayed by it. This means if you first add an image, anything further that is drawn will appear on top of that (if it overlaps the image).

Below is a demonstration of doing that. Note I borrowed some of the code and the sample image from the python-course.eu page: Canvas Widgets in Tkinter. It describes the drawing facilities supplied by Canvas widgets.

from PIL import Image, ImageTk
import tkinter as tk
from tkinter.constants import *

canvas_width, canvas_height = 300, 300

root = tk.Tk()

canvas = tk.Canvas(root, width=canvas_width, height=canvas_height)
canvas.pack()

img = ImageTk.PhotoImage(file='rocks.png')
canvas.create_image(20, 20, anchor=NW, image=img)

# Draw something on top of image.
points = [100, 140, 110, 110, 140, 100, 110, 90, 100, 60, 90, 90, 60, 100, 90, 110]
canvas.create_polygon(points, outline='green', fill='yellow', width=3)

root.mainloop()

Here's the rocks.png image the code uses.

Screenshot of result:

screenshot

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