Turning RGB Values Into The Basic Colors Of The Rainbow Using Python

Here I am again, I guess. Here is what I got so far:

from PIL import Image
from tkinter import filedialog as fd
from webcolors import rgb_to_name
from pyautogui import press, typewrite, hotkey
import time

filename = fd.askopenfilename()
im = Image.open(filename, 'r')
pix_val = list(im.getdata())

def GetColor(R, G, B):
    Final = ""
    named_color = rgb_to_name((R, G, B), spec='css3') # Here
    return Final

for i in pix_val:
    press('q')
    press('t')
    typewrite('.give ' + GetColor(i[0], i[1], [2]))
    press('enter')
    time.sleep(3)

Now the goal is to make the script automatically turn the RGB values into simple colors like Black, Red, White, Orange, Blue, Purple, Green... you know. No intense colors like firebrick. I'm sure there is probably a way to do it by just making a simple map and if the colors match near that color then it would say it is that color. Example:

XYZ = {["Red", 255, 0, 0], ["Blue", 0, 0, 255], ["Green", 0, 255, 0]...}

However, I want a simple little import that is already coded :/ Any help is much appreciated.


The problem with this is there is, in general, no good shortcut. You have to determine the distance from each pixel to each color in the palette, and keep the smallest of those distances.

Here's one that maps to the 16 colors in the HTML4 standard set:

import math
from PIL import Image

colors = [
    ("black", (0, 0, 0)),
    ("silver", (192, 192, 192)),
    ("gray", (128, 128, 128)),
    ("white", (255, 255, 255)),
    ("maroon", (128, 0, 0)),
    ("red", (255, 0, 0)),
    ("purple", (128, 0, 128)),
    ("fuchsia", (255, 0, 255)),
    ("green", (0, 128, 0)),
    ("lime", (0, 255, 0)),
    ("olive", (128, 128, 0)),
    ("yellow", (255, 255, 0)),
    ("navy", (0, 0, 128)),
    ("blue", (0, 0, 255)),
    ("teal", (0, 128, 128)),
    ("aqua", (0, 255, 255))
]

def distance(a,b):
    dx = a[0]-b[0]
    dy = a[1]-b[1]
    dz = a[2]-b[2]
    return math.sqrt(dx*dx+dy*dy+dz*dz)

def findclosest(pixel):
    mn = 999999
    for name,rgb in colors:
        d = distance(pixel, rgb)
        if d < mn:
            mn = d
            color = name
    return color

im = Image.open("pacmanmaze.png", 'r')
pix_val = im.getdata()

for i in pix_val:
    print(findclosest(i))