ofxColor

Some color manipulation issues seem to regularly pop up:

  • RGB <-> HSV conversion
  • map, lerp, normalize colors
  • floating point vs 8-byte colors
  • color matching in HSV or RGB space
  • color math and blending
  • being able to do fast per-pixel operations, but also
  • being able to manage more abstract palettes of colors with sorting operations

OpenCV can do a lot of the above, but ofxColor is working towards an OF-style color library that stands on its own.

It’s a work in progress, and I currently only have the basic architecture and core functions laid out. ofBaseColor (the OOP-interface to the routines) needs the most work. I’m not in the middle of a color-intensive project right now, so I can’t test everything… but I wanted to get a basic structure that will work in the future.

It’s available via SVN with a C::B example here.

Any help/suggestions/criticism/etc. would be hugely appreciated!

Here’s output from the demo app, to give a feeling for how it works:

  
  
ofxColorf myColor(.1, .2, .3);  
(0.1, 0.2, 0.3, 1)  
  
myColor.setRange(255);  
(25.5, 51, 76.5, 255)  
  
myColor.setMode(OF_COLOR_HSV);  
(148.75, 170, 76.5, 255)  
  
myColor.normalize();  
(0.583333, 0.666667, 0.3, 255)  
  
myColor.setMode(OF_COLOR_RGB);  
(0.1, 0.2, 0.3, 255)  
  
myColor.reset();  
(0, 0, 0, 1)  
  
myColor.set(.1, .2, .3).setRange(255).setMode(OF_COLOR_HSV).normalize().setMode(OF_COLOR_RGB);  
(0.1, 0.2, 0.3, 255)  
  
myColor.setRed(1.1).clamp();  
(1, 0.2, 0.3, 255)  
  
target.set(0, 1, 0).setRange(255);  
myColor.lerp(target, .8);  
(0.2, 0.84, 0.06, 255)  
  
myColor.set(0, 1, 0).distance(target.set(255, 0, 0);  
1.41421  
  

hey looks great !

sorry, I didn’t try it yet (gonna hook it up later today), but is this the alpha or the scale range?

(0.583333, 0.666667, 0.3, 255)

I read it as alpha (just skimming your post), but that made me confused me about this:

  
myColor.normalize();  
(0.583333, 0.666667, 0.3, 255)  

which would make sense if it’s scale range (ie, R /= Range).

take care!
zach

Thanks!

You read it correctly, that’s my bad! I’ve tested the core functions more than the ofxColorBase class.

Just fixed.

  
  
ofxColorf myColor(.1, .2, .3);  
(0.1, 0.2, 0.3, 1)  
  
myColor.setRange(255);  
(25.5, 51, 76.5, 255)  
  
myColor.setMode(OF_COLOR_HSV);  
(148.75, 170, 76.5, 255)  
  
myColor.normalize();  
(0.583333, 0.666667, 0.3, 1)  
  
myColor.setMode(OF_COLOR_RGB);  
(0.1, 0.2, 0.3, 1)  
  
myColor.reset();  
(0, 0, 0, 1)  
  
myColor.set(.1, .2, .3).setRange(255).setMode(OF_COLOR_HSV).normalize().setMode(OF_COLOR_RGB);  
(0.1, 0.2, 0.3, 1)  
  
myColor.setRed(1.1).clamp();  
(1, 0.2, 0.3, 1)  
  
target.set(0, 1, 0).setRange(255);  
myColor.lerp(target, .8);  
(0.2, 0.84, 0.06, 1)  
  
myColor.set(0, 1, 0).distance(target.set(255, 0, 0);  
1.41421  
  

I’d love to help. I’ve written my own color class, as well. Returns RGB as uint and does RGB <-> HSV. I was kind of disappointed in ofx’s color processing (lack thereof) when I got into it. Really surprising as a visual language should have HSV support and color manipulation.

Hey LetsGoOutside, describe what you’re interested in adding/changing and I can give you commit access to the SVN.

Actually, just took a look and it’s very thorough. Nicely done.

Hi

I’ve tried using ofxColor in my own project, using it to interpolate between 2 colours. I’ve got some feedback for ofxColor and also ofColor:

  • First of all, it’s nice to have RGB/HSV conversion, and general manipulation. ofColor is rather sparse by comparison :smiley:
  • I like the setRange call.
  • It would be nice for ofxColor to maybe inherit from ofColor, so the extension class could be used where ofColor is currently.
  • The getters (getRed, getBlue, etc) aren’t const. I understand why, given the call to update, but I wouldn’t normally expect such behaviour from a colour component accessor.
  • I guess the intention is for ofxColor to be used when more sophisticated functionality is required, but it would be good to see some improvements to ofColor (e.g., operators, 0…1 float range, although that’s maybe just my preference).

Other than that, it all looks pretty powerful.

Thanks so much for the feedback macdonag!

There was an earlier version of ofxColor that inherited ofColor. The problem is that ofColor is not templated, so it would require you to always use floats to represent your colors. On the other hand ofxColor lets you use whatever datatype you want. This comes in really handy when you’re doing per-pixel processing on images where colors are stored in 24 bits, or 3 bytes of RGB.

It is slightly non-intuitive to have non-const getters. Maybe the better approach would be to have const getters that require you to call update() yourself, and then some lazy-non-const getters as well? Something like getUpdatedHue(), getNewHue(), or getCurHue().

(The lazy evaluation comes in really handy for sorting algorithms, keeping things from being converted multiple times.)

I think ofColor doesn’t need to be too complex, but it should at least mirror Processing. i.e.:

  • set range
  • set color mode (or at least conversion)
  • blend
  • lerp

Sounds good. Maybe you could replace the current ofColor with a typedef ofxBaseColor? I’ll be trying out the lerp later.

Incidentally, I’ve had to write a couple of additional lerp functions for handling points and rectangles. Would it be worth adding them to the appropriate classes or creating a collection of lerp functions in one place?

ofxBaseColor is way too big to belong in OF, but it would be nice to have a templated ofColor.

Regarding the other lerps, that’s a whole other discussion. What I’d do is: post in the feature requests forum along with the code you’ve written and get a discussion started.

Fair point. I’ll do that once I’m happy with it.