How do I make an automatic color namer?

I’m trying to create a code that can detect the hue of a RGB value.
ex: hueOf(255, 0, 0) == "Red"

However, I need it to be more specific than just red blue and green. For example, hueOf(205, 105, 25) would need to return "Orange".

How can I do this efficiently?
I don’t need the whole code, just some tips


this is an example of the type of issues I am coming into. My current detector sees the high B value and that the other values aren’t close to the B value, so it labels the color Blue even though it’s clearly pink

This is my current script (pretty messy & could be optimized, i know):

local function getHue(Value)
		local function prox(Ref, Val, Prx)
			if Ref - Prx <= Val and Ref + Prx >= Val then
				return true
			end
			return false
		end
		local Hues = {R = "Red", B = "Blue", G = "Green", RB = "Purple", BR = "Purple", BG = "Teal", GB = "Teal", GR = "Yellow", RG = "Yellow", RGB = "Gray", GBR = "Gray", BRG = "Gray"}
		local Hue = ""
		if Value.R > Value.G and Value.R > Value.B then
			Hue = Hue.."R"
			if prox(Value.R, Value.B, 20) then Hue = Hue.."B" end
			if prox(Value.R, Value.G, 20) then Hue = Hue.."G" end
		end
		if Value.G > Value.R and Value.G > Value.B then
			Hue = Hue.."G"
			if prox(Value.G, Value.B, 20) then Hue = Hue.."B" end
			if prox(Value.G, Value.R, 20) then Hue = Hue.."R" end
		end
		if Value.B > Value.G and Value.B > Value.R then
			Hue = Hue.."B"
			if prox(Value.B, Value.R, 20) then Hue = Hue.."R" end
			if prox(Value.B, Value.G, 20) then Hue = Hue.."G" end
		end
		return Hues[Hue] or "Random"
	end

You can use BrickColors to get a color’s closest BrickColor name

local brickColor = BrickColor.new(Color3.fromRGB(255, 0, 0))
print(brickColor.Name) -- "Really red"

This may give color names that are more specific than required your purposes, but its a good place to start.

1 Like

That’s actually really smart, thanks! Youre right though, it is a bit more specific than I need, so I’ll keep this open in case someone else has a more mathematical approach. Definitely will be my backup plan, though

2 Likes

Here’s an idea that will allow you to specify which colors can be selected as well as the color display names should be.

I’m not entirely sure that calculating the difference between two colors by the difference of their RGB components is the most accurate metric, but if you specify enough colors I don’t think it would be an issue

-- dictonary mapping display color names to comparison
local ColorNames = {
	Red = BrickColor.new("Bright red").Color,
	Yellow = BrickColor.new("Bright yellow").Color,
	Orange = BrickColor.new("Bright orange").Color,
	Green = BrickColor.new("Bright green").Color,
	Black = Color3.fromRGB(0, 0, 0),
	-- etc.
}

local function GetClosestColor(matchColor)
	local bestColor
	local minDistance = math.huge
	
	for colorName, color in pairs(ColorNames) do
		-- calculate mean squared error as distance
		local delta = (color.R - matchColor.R)^2 + (color.G - matchColor.G)^2 + (color.B - matchColor.B)^2
		if delta < minDistance then
			bestColor = colorName
			minDistance = delta
		end
	end
	
	return bestColor
end

local colorName = GetClosestColor(Color3.fromRGB(255, 0, 0))
print(colorName) -- "Red"
2 Likes

:+1: This is probably the best way I could do it without being super complex. Thanks!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.