1

I need to do this on a Windows computer. Are there any programs that provides such a capability? I will be just as satisfied if I can implement this capability in python. I know in python I can get the (rgb_values) at (xy_position) in (my_image.png) as follows:

xy_position = (100, 100)
img = PIL.Image.open("my_image.png")
rgb_image = img.convert("RGB")
rgb_values = rib_image.getpixel(xy_position)

I am also familiar with tkinter, but haven't found a way to make a python program that will pass the appropriate value of (xy_position) to the code above. Using tkinter isn't required.

I looked at all tkinter widgets and it seems none solve the problem.

Ted Ersek
  • 119
  • 4

1 Answers1

0

Here's a basic app with a working example - you'll probably want to tweak the window geometry if you're working with images larger than 600x600! You could make it dynamic if you call something like self.geometry(f'{dim_x}x{dim_y + 20}') after declaring dim_x and dim_y (the extra 20 pixels on the y axis is to leave room for the label)

import tkinter as tk
from PIL import Image, ImageTk
from pathlib import Path


class App(tk.Tk):
    def __init__(self):
        super().__init__()
        self.geometry=('600x600')
        
        self.img_path = Path(r'C:\Path\To\image.png')
        self.img = Image.open(self.img_path)
        self.img_rgb = self.img.convert('RGB')
        dim_x, dim_y = self.img_rgb.size
        self.img_tk = ImageTk.PhotoImage(self.img_rgb.resize((dim_x, dim_y)))
        
        self.canvas = tk.Canvas(self)
        self.canvas.create_image(dim_x // 2, dim_y // 2, image=self.img_tk)
        self.canvas.pack(expand=True, fill=tk.BOTH)

        self.rgb_var = tk.StringVar(self, '0 0 0')
        self.rgb_label = tk.Label(self, textvariable=self.rgb_var)
        self.rgb_label.pack()

        self.bind('<Motion>', lambda e: self.get_rgb(e))

    def get_rgb(self, event):
        x, y = event.x, event.y
        try:
            rgb = self.img_rgb.getpixel((x, y))
            self.rgb_var.set(rgb)
        except IndexError:
            pass  # ignore errors if the cursor is outside the image


if __name__ == '__main__':
    app = App()
    app.mainloop()
JRiggles
  • 4,847
  • 1
  • 12
  • 27
  • 1
    That looks very promising. I changed (self.img_path) to one for an image on my computer. When I run the code I get RuntimeError: Too early to create image: no root window ----- Do you know how to fix that? – Ted Ersek Oct 28 '22 at 20:14
  • 1
    Missing `super().__init__()`. Just use a label for the image and bind on that label instead of root window. Use image in canvas if the image is larger than the window. – acw1668 Oct 28 '22 at 20:19
  • @acw1668 Good catch! I'll fix that – JRiggles Oct 29 '22 at 14:51
  • @JRiggles, When I run the latest version I get "TypeError: getpixel(() takes 2 positional arguments but three were given." How do we fix that? – Ted Ersek Oct 31 '22 at 13:12
  • The argument for `xy` in `getpixel` needs to be a tuple. Looks like I missed some parentheses when transcribing my answer! Fixed! – JRiggles Oct 31 '22 at 13:37