What would be the best design pattern to implement a 'color' data structure (in C#)? I would like to be able to represent a color in any of the color spaces - RGB, HSV, XYZ, Yxy, Luv, Lab, HSL etc.. and I would like to be able to convert from one format to another. I would like to support a fixed number of color spaces.
-
1What's the application area? Even a difference as simple as screen/print is so big that there's no common answer for the two. And if you say "all areas", you have to go beyond visual light/human sight. – MSalters Jan 24 '11 at 13:38
-
1You sound familiar: http://stackoverflow.com/questions/4770921/how-would-i-represent-an-hsl-and-an-rgb-color-as-a-class-in-c/4778968#4778968 – Cody Gray - on strike Jan 24 '11 at 13:38
1 Answers
You could create a helper class that can convert from one to another, so you can just use simple classes like Vector3
or of some sort to keep your data.
Because RGB, HSV and all are just 3 values, a Vector3
can be used for all the data. But then, it is up to the programmer to not get the wrong values into the wrong methods.
To assure the right type of value. We could use some Vector3
as the base class and then let every type (like RGB) inherit from the base class.
You could even choose to also create an "interclass" that's called Color
. Which is an abstract class. The RGB
class could then implement all abstract defined methods.
So you get:
Vector3
(most languages have some sort of class like this)abstract Color extends Vector3
(has abstract methods)RGB extends Color
(implements all methods for conversion to other classes).
The abstract methods in Color that convert, will just return a Color itself. So you can override the method just like that.

- 6,384
- 4
- 43
- 78
-
Yeah, don't leave it up to the programmer to keep the color spaces straight. That's *way* too easy to break. Take advantage of type safety when it's available. – Cody Gray - on strike Jan 24 '11 at 13:52
-
1IMHO your class hierarchy is broken. By inheriting from Vector3 you expose your internal data storage. Vector3 only works for RGB (and there I would prefer a single integer and bit shifting for space and performance reasons) and already stops working if you want to support RGBA (RGB with alpha component). I would prefer composition over inheritance and go with a single type and conversion constructors and methods to convert between color spaces. See e.g. Qt's QColor: http://doc.qt.nokia.com/latest/qcolor.html – Frank Osterfeld Jan 24 '11 at 21:19
-
@Frank Seems like a nice idea indeed. It depends on what you want I think. Indeed, extending the `Vector3` isn't that nice, but building a wrapper class around it would do fine I think. – Marnix Jan 24 '11 at 23:10
-
@Frank: I agree with almost everything you said (hence, +1), but do you *really* think it's necessary to bit-shift the RGB color value? I mean, are you really saving that much space and gaining that much performance, and is that marginal benefit really worth the trouble? And if it is, why stop there? You could store the values in other color spaces in a single integer, too, but even you seem to agree that isn't worth the effort. – Cody Gray - on strike Jan 25 '11 at 06:58
-
@Cody Gray: One could consider that premature optimization, but I don't see the single int version that much effort either. One basically needs three getters and setters each to get/set the single components. If those are inline (if the language allows that), one can use them internally without penalty and has to do no further bit shifting in the code. And whether to store other color spaces separately or convert them as needed to/from RGB(A) or another color space probably depends whether you have a main use case/color space or not. – Frank Osterfeld Jan 25 '11 at 09:33
-
@Frank: Fair enough. I've just got an eye towards future maintainability, and the knowledge that far too many programmers have a very poor understanding of bit-shifting. It does seem a bit like premature optimization to me. ;-) – Cody Gray - on strike Jan 25 '11 at 09:36