Mike - 3 months ago 12

SQL Question

I have a rgb value and if it doesn't exist in the color table in my database I need to find the closest color. I was thinking of comparing all values and finding the difference(in red,green,and blue) then take the average. The lowest average deviation should be the closest color. There seems to me like there should be a better way. Any ideas?

Answer

Consider a color as a vector in 3-dimensional space, you can then easily compute the difference by using 3d pythagoras:

```
d = sqrt((r2-r1)^2 + (g2-g1)^2 + (b2-b1)^2)
```

However, note that due to colors being subject to interpretation by not-so-perfect eyes, you might want to adjust the colors to avoid them having the same importance.

For instance, using a typical weighted approach:

```
d = sqrt(((r2-r1)*0.3)^2 + ((g2-g1)*0.59)^2 + ((b2-b1)*0.11)^2)
```

Since eyes are most sensitive to green, and least sensitive to blue, two colors that differ only in the blue component must thus have a larger numeric difference to be considered "more different" than one that is the same numeric difference in the green component.

There's also various ways to optimize this calculation. For instance, since you're not really interested in the actual `d`

value, you can dispense with the square root:

```
d = ((r2-r1)*0.30)^2
+ ((g2-g1)*0.59)^2
+ ((b2-b1)*0.11)^2
```

Note here that in many C-syntax-based programming languages (like C#), `^`

does not mean "raise to the power of", but rather "binary exclusive or".

So if this was C#, you would use `Math.Pow`

to calculate that part, or just expand and do the multiplication.

**Added**: Judging by the page on Color difference on Wikipedia, there's various standards that try to handle perceptual differences. For instance, the one called CIE94 uses a different formula, in the `L*C*h`

color model that looks like it's worth looking into, but it depends on how accurate you want it to be.