I have ten hex / rgb values for colours (they're skin tones) - I want to be able to find the closest match to a specific hex / rgb value.
Would I somehow iterate from the start colour until I fall within a specific range? But how do I organize the ranges?
I'll be honest, I have absolute zero idea how to do it, or what even to search for, so any help, or a nod in the right direction would be greatly appreciated.
Cheers
First off, it's not necessarily a programming question but...
Euclidean distance is a good method for this. As an example:
Using regular html color names, BlueViolet (#8A2BE2) and GoldenRod (#DAA520), which is closer to LightSeaGreen (#20B2AA)? Split the 3 hex values to a 3D vector as such:
BV = 138,43,226
GR = 218,165,32
LSG = 32,178,170
Using the formula:
d(p,q) = sqrt((px - qx)^2 + (py - qy)^2 + (pz - qz)^2)
d(BV,LSG) = sqrt((138-32)^2 + (43-178)^2 + (226-170)^2)
d(BV,LSG) = sqrt(11236 + 18225 + 3136)
d(BV,LSG) = sqrt(32597)
d(BV,LSG) = 180.546
d(GR,LSG) = sqrt((218-32)^2 + (165-178)^2 + (32-170)^2)
d(GR,LSG) = sqrt(34596 + 169 + 19044)
d(GR,LSG) = sqrt(53809)
d(GR,LSG) = 231.967
So as you can see d(BV,LSG)
is smaller than d(GR,LSG)
so BlueViolet is closer to LightSeaGreen than GoldenRod is.
I can offer you to use Euclidean distance between 2 colors. If you have any 2 colors, for example #89a839 and #ad9009 , you can convert it into 3 dimentional vectors, and you will get this 2 vectors (ad,90,09) and (89,a8,39); then convert numbers to decimal range. and just count euclidean distance beetween this two points
d = sqrt((x1-x2)^2,(y1-y2)^2,(z1-z2)^2,)
Just count this distance beetween your color and for all colors you have, and find smallest value, then your color will closest to specific color.
If you have any problems for coding this, feel free to ask.
While Euclidean distance over RGB might help, it would be much better to use a proper color model. I would advise LCH or at least HSL. Then assign weights to each channel. For instance, for human eye, lightness is perceived at logarithmic scale. Tuning down its effect might give better matches. So, following would never happen:
#400 (very dark red) matches #222 (almost blackish gray, distance 12) instead of #800 (dark red, distance 16)