Question

I have 4 colors that I converted from RGB to CIELAB L*a*b* model.

  1. How can I calculate mix of these 4 colors when I have (L,a,b) for each such color?

  2. How can I calculate same mix, if I want to put weights (w1, w2, w3, w4) on such 4 colors, having 1 maximum and 0 minimum (none) weight?

Was it helpful?

Solution

Assuming you have a structure like this:

typedef struct LabColor {
    uint8_t L;
    uint8_t a;
    uint8_t b;
} LabColor;

and an array of 4 of them:

LabColor colors[4];
getMeSomeColors (colors);

and weights:

float weights[4];
getMeSomeWeights (weights);

One possible blending method would be this:

float LSum = 0.0;
float aSum = 0.0;
float bSum = 0.0;
float weightSum = 0.0;
for (int i = 0; i < 4; i++)
{
    LSum += ((float)colors [ i ].L * weights [ i ]);
    aSum += ((float)colors [ i ].a * weights [ i ]);
    bSum += ((float)colors [ i ].b * weights [ i ]);
    weightSum += weights[i];
}
LabColor result;
result.L = (uint8_t)(LSum / weightSum);
result.a = (uint8_t)((aSum / weightSum) + 127);
result.b = (uint8_t)((bSum / weightSum) + 127);

This assumes weights are all between 0 and 1. If not, then you'll have to do some clamping. If the weights sum to 1, then you can skip the division step.

There are an infinite number of other ways to blend the colors. If this one doesn't do what you want, you'll need to give more specifics as to what you do want.

OTHER TIPS

The most realistic results will come from converting your L*a*b* values to a linear (not gamma-corrected) RGB space, summing those values, and converting back. This is how physical light sources interact.

The L*a*b* color space wasn't invented for color manipulation, as it's inherently non-linear.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top