2

Let's say I have color 'FOO', and it is stored in RGB format. I need to recolor 'FOO' so it matches the closest color in a list of colors. Doing this on the fly, couldn't I view the RGB values from each color as points on a 3D grid (r=x, g=y, b=z) and compute the distance between point 'FOO' vs the points from each color in the list?

The closest point to 'FOO' would be the replacement color?

Jeffrey Kern
  • 2,024
  • 20
  • 40
  • That's an interesting idea (Euclidean distance as colour "distance"), but the only way to tell if interpreting colours as geometry is to try it. I haven't heard of this before, but I'd like to hear how it turns out. What do you do if you have two points equidistant from your source point? The two equidistant colours could be very different from each other. How do you choose which to remap to? – FrustratedWithFormsDesigner Jun 29 '10 at 17:28
  • I wish I could try it out, I am at work and my computing device is pad and paper, my cellphone, a calculator, and a cash register. I jot theories down and try to implement em at home. – Jeffrey Kern Jun 29 '10 at 17:32
  • @Jeffrey Kern: Heh I've been there. I guess you're surfing SO on the cellphone? Well, the main problem I see with this theory is the equidistant point problem. If I knew more about colour theory, I'd probably have more to say, but instead I'll just watch... ;) – FrustratedWithFormsDesigner Jun 29 '10 at 17:34
  • If there's a tie between multiple points, I'd go with the first one. But I guess that's a judgement call for the programmer to make, or a prompt to ask the end user what to do. – Jeffrey Kern Jun 29 '10 at 17:36
  • @frustrased Yup. Typing out questions on a cellphone for SO is a pain lol :) – Jeffrey Kern Jun 29 '10 at 17:39
  • @Jeffrey Kern: How do you define the "first one" in 3d space? :P – FrustratedWithFormsDesigner Jun 29 '10 at 17:44
  • R=x coordinate of a point, with G=y and B=z. Made up together these values should make a point in 3d space. – Jeffrey Kern Jun 29 '10 at 17:55
  • Yes, but if points B and C are the same Euclidean distance from point A, how do you define which of B and C is "first"? – FrustratedWithFormsDesigner Jun 29 '10 at 18:02
  • Ooooh, I misunderstood you haha. The first one would be the first one checked against in the for/each loop. Eg, if thisDist < curDist, curDist=thisDist and curColor = colorIterator. If I changed the equality operator to <= the last one would be selected. – Jeffrey Kern Jun 29 '10 at 18:17

1 Answers1

1

In theory, yes. In reality, computing the closest color is non-trivial if you want to do it well. Just for example, people's eyes are much more sensitive to changes in brightness than color shifts, especially toward the ends of the color range (i.e., toward extreme reds or blues).

At least if you don't mind some extra work in the computation, you'll want to use one of the standard "delta E" computations (in your case, you'll want to minimize delta E). Note that these all (all I've worked with anyway) work in the CIE Lab* color space. In a typical case, you'll start with RGB, which you'll need to convert to Lab* first.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • Would this work if I'm targeting a custom palette? E.g, original image contains 8 different colors ( red, green, yellow, peach, etc.) whereas the target palette contains black, white, and 4 shades of blue? – Jeffrey Kern Jun 29 '10 at 17:51
  • @Jeffrey: Yes, with the proviso that it's doubtful anything will work very well in that kind of situation -- to the point that it might be a bit of a waste of time. OTOH, with a palette of only 8 colors, you can pre-compute the output for each of the 8 possible inputs, and convert each pixel as a trivial table lookup. – Jerry Coffin Jun 29 '10 at 18:12
  • @Jeffrey: also, instead of just picking the *first* equal match as you mentioned in your comment, you might want to keep track of an accumulated error, and pick the one that minimizes the overall error (c.f., Floyd-Steinberg dithering: http://en.wikipedia.org/wiki/Floyd%E2%80%93Steinberg_dithering). – Jerry Coffin Jun 29 '10 at 18:15
  • the colors in the source image will change with the image loaded but for the most part the target palette won't. I'm just looking for a solution that will allow me to recolor images on the fly when they're rendered wit GDI+. It's a waste making 6 images for 1 object when u can recolor haha. And if I have 100 objects I'd rather not handle 600 images (6 different target palettes including original coloring) – Jeffrey Kern Jun 29 '10 at 18:31