Color arithmetic (getting average, etc.)

I am trying to do calculation on color data type. Say, I want to get an average of two colors as below, and say I cannot access the color values 0 and 255 themselves directly:

color c1 = color(0);
color c2 = color(255);
int avg = (c1 + c2) / 2;
background(avg);

The code above does not work. I can instead calculate each channel separately as below:

color c1 = color(0);
color c2 = color(255);
float r = (red(c1) + red(c2)) / 2;
float g = (green(c1) + green(c2)) / 2;
float b = (blue(c1) + blue(c2)) / 2;
background(r, g, b);

The code above does work, but I feel I can shorten it by doing calculation on the color data themselves without separating into each channel. I know I can do bit shifting to make it faster but do you have any suggestions? Some type of data conversion, maybe?

Generally I use lerpColor(). It’s essentially what you’ve created but it will do the low level work and account for HSB colors. If you’re interested in seeing how it works, here’s a link to the source code.

1 Like

lerpColor is the way to do color interpellation. For individual channels or for other arithmetic operations on color, use red()/green()/blue() – or use bit shifting if you need speed.

The reason you cannot average color ints directly is due to the bit structure:

From a technical standpoint, colors are 32 bits of information ordered as AAAAAAAARRRRRRRRGGGGGGGGBBBBBBBB where the A’s contain the alpha value, the R’s are the red value, G’s are green, and B’s are blue. Each component is 8 bits (a number between 0 and 255). These values can be manipulated with bit shifting.

So: you cannot carry over from R to G, or G to B, they are separate. Certain numbers will actually work – but many won’t, because carrying over across bits is exactly what normal arithmetic operations on ints do.

1 Like

The other answers are already great. You can’t operate on the color values themselves, unless you use something like the lerpColor() function.

I’ll also point out when it comes to colors, calculating the true average is a bit more complicated than averaging each individual component.

Here is a good post that discusses the basics:

Googling “color averaging” will also return a ton of promising results.

2 Likes

Good point. If you do decide to do CIELAB color space rather than RGB, for greater perceptual uniformity, here are some resources for CIELAB in Processing:

Two library options, Chroma and part of giCentre utils:

Two stand-alone examples with CIELAB colorspace conversion:

1 Like