# Color arithmetic (getting average, etc.)

**URL:** <https://discourse.processing.org/t/color-arithmetic-getting-average-etc/9801>\
**Category:** Coding Questions\
**Created:** [March 30, 2019, 9:35pm UTC](https://discourse.processing.org/t/color-arithmetic-getting-average-etc/9801 "2019-03-30T21:35:57Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![cdaein](https://avatars.discourse-cdn.com/v4/letter/c/8e7dd6/32.png) [@cdaein](https://discourse.processing.org/u/cdaein)\
**Post date:** [March 30, 2019, 9:35pm UTC](https://discourse.processing.org/t/color-arithmetic-getting-average-etc/9801/1 "2019-03-30T21:35:58Z")

</div>

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:

```java
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:

```java
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?

---

<div class="post-metadata">

**Author:** ![figraham](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/figraham/32/4161_2.png) [@figraham](https://discourse.processing.org/u/figraham)\
**Post date:** [March 31, 2019, 3:13am UTC](https://discourse.processing.org/t/color-arithmetic-getting-average-etc/9801/2 "2019-03-31T03:13:23Z")

</div>

Generally I use [`lerpColor()`](https://processing.org/reference/lerpColor_.html). 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](https://github.com/processing/processing/blob/676bcec1ca79aa0fceec2445e5febecdf9d3eb53/core/src/processing/core/PGraphics.java#L8119).

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [March 31, 2019, 7:19pm UTC](https://discourse.processing.org/t/color-arithmetic-getting-average-etc/9801/3 "2019-03-31T19:19:17Z")

</div>

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.

- [color / Reference / Processing.org](https://processing.org/reference/color_datatype.html)

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](https://processing.org/reference/rightshift.html).

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.

---

<div class="post-metadata">

**Author:** ![Kevin](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kevin/32/2297_2.png) [@Kevin](https://discourse.processing.org/u/Kevin)\
**Post date:** [March 31, 2019, 7:53pm UTC](https://discourse.processing.org/t/color-arithmetic-getting-average-etc/9801/4 "2019-03-31T19:53:32Z")

</div>

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:

> <https://stackoverflow.com/questions/649454/what-is-the-best-way-to-average-two-colors-that-define-a-linear-gradient>

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

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [March 31, 2019, 8:21pm UTC](https://discourse.processing.org/t/color-arithmetic-getting-average-etc/9801/5 "2019-03-31T20:21:15Z")

</div>

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:

- [https://github.com/neilpanchal/Chroma](https://github.com/neilpanchal/Chroma)
- [http://gicentre.org/utils/reference/org/gicentre/utils/colour/CIELab.html](http://gicentre.org/utils/reference/org/gicentre/utils/colour/CIELab.html)

Two stand-alone examples with CIELAB colorspace conversion:

- [https://www.openprocessing.org/sketch/449261/](https://www.openprocessing.org/sketch/449261/)
- [https://forum.processing.org/two/discussion/6903/unexpected-result-in-color-conversion-from-lab-to-rgb](https://forum.processing.org/two/discussion/6903/unexpected-result-in-color-conversion-from-lab-to-rgb)
