pineApple
pineApple

Reputation: 1

Python tkinter get color from canvas

I have created a simple Tkinter application with a canvas widget like this:

from tkinter import *
root = Tk()
root.geometry("500x500-500+500")

canvas = Canvas(root, width = 400, height = 400, bg = "white")
canvas.pack()

canvas.create_line(0, 0, 200, 100, width = 20, fill = "black")

root.mainloop()

My question is, how can I get the color of the canvas in a specific position? Say for instance I clicked somewhere on the line, how can I get back the color "black" from that?

In other words, if I wanted a function like this,

def getColor(cnvs, event = None):
   x = event.x
   y = event.y
   # somehow gets the color of cnvs at position (x, y) and stores it as color
   return color

how would I go about doing that?

Upvotes: 0

Views: 1973

Answers (2)

DonH
DonH

Reputation: 21

I tried the PIL ImageGrab approach today and found that ImageGrab on a Mac returned the screen background, not tkinter or canvas contents.

Here's a solution that works, at least on a Mac running Monterrey

Use the tkinter.colorchooser dialog. See: https://docs.python.org/3/library/tkinter.colorchooser.html

The dialog displays the system color picker and returns a tuple containing an rgb tuple and a string usable as a color in tkinter.

At least on a Mac, the color picker includes an eye dropper that works on the canvas (or anywhere on your screen).

I don't know whether the same is available in Windows.

Here's a fairly short demo program. Run the program, click the button, then select the eyedropper in the color picker (you also have to click "OK" in the color picker.

# ColorChooserDemo.py

import tkinter as tk
from tkinter import colorchooser


class EyeDropperDemo(tk.Tk):
    def __init__(self):
        super().__init__()
        canvas = tk.Canvas(self, bg='gray', width=200, height=120)
        canvas.pack()
        canvas.create_rectangle(40, 40, 80, 80, fill='red')
        canvas.create_rectangle(120, 40, 160, 80, fill='blue')
        tk.Button(self, text='Color Picker', command=self.eyedropper).pack()

    def eyedropper(self):
        color: None | tuple[tuple, str] = tk.colorchooser.askcolor()
        print(f'askcolor() returned {color}')
        if color is not None:
            tkinter_color = color[1]
            tk.Label(self, text=f'You Picked {tkinter_color}', bg=tkinter_color).pack()


if __name__ == '__main__':
    app = EyeDropperDemo()
    app.mainloop()

Upvotes: 0

acw1668
acw1668

Reputation: 47183

You can take a screen shot of the canvas using Pillow.ImageGrab module and get the required pixel color from the snapshot image:

from PIL import ImageGrab

def get_color(cnvs, event):
    x, y = cnvs.winfo_rootx()+event.x, cnvs.winfo_rooty()+event.y
    # x, y = cnvs.winfo_pointerx(), cnvs.winfo_pointery()
    image = ImageGrab.grab((x, y, x+1, y+1)) # 1 pixel image
    return image.getpixel((0, 0))

Note that the color returned is in (R, G, B) format.

Upvotes: 1

Related Questions