# 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