Here is code to Convert RGB <-> HSB
Here is code to Convert RGB <-> HSB
- Subject: Here is code to Convert RGB <-> HSB
- From: Duncan Champney <email@hidden>
- Date: Mon, 11 Feb 2008 15:22:51 -0500
My application needs to be able to make HSB adjustments to all the
pixels in RGB NSImages that are potentially quite large. (e.g. take an
RGB pixel, reduce the brightness by 20%, and increase the saturation
by 50%)
The NSColor class has excellent support for this, but you have to
create an instance of NSColor for every value you need. I'd need to
create several NSColor objects for every pixel on the screen, each
time my app updates it's image. This would involved allocating and
releasing millions of objects for each screen update.
Instead, I found some code online that lets me convert back and forth
between RGB and HSB values. It needed some tweaking to work with
Cocoa. The original code was written to use hue values from 0 to 6. I
changed it to use hue in the range 0 - 1, as is the norm in Cocoa. I
also had to change around some of the math library calls to make them
work in Cocoa.
Here is the code I ended up with:
//------------------
//---header file
#define RETURN_HSV(h, s, v) {HSV.H = h; HSV.S = s; HSV.V = v; return
HSV;}
#define RETURN_RGB(r, g, b) {RGB.R = r; RGB.G = g; RGB.B = b; return
RGB;}
#define UNDEFINED 0
// Theoretically, hue 0 (pure red) is identical to hue 6 in these
transforms. Pure
// red always maps to 6 in this implementation. Therefore UNDEFINED
can be
// defined as 0 in situations where only unsigned numbers are desired.
typedef struct {float R, G, B;} RGBType;
typedef struct {float H, S, V;} HSVType;
//------------------
//--The code
#include <math.h>
HSVType RGB_to_HSV( RGBType RGB )
{
// RGB are each on [0, 1]. S and V are returned on [0, 1] and H is
// returned on [0, 1]. Exception: H is returned UNDEFINED if S==0.
float R = RGB.R, G = RGB.G, B = RGB.B, v, x, f;
int i;
HSVType HSV;
//x = fminx(R, G, B);
x = fminf(R, G);
x = fminf(x, B);
//v = fmaxf(R, G, B);
v = fmaxf(R, G);
v = fmaxf(v, B);
if(v == x) RETURN_HSV(UNDEFINED, 0, v);
f = (R == x) ? G - B : ((G == x) ? B - R : R - G);
i = (R == x) ? 3 : ((G == x) ? 5 : 1);
RETURN_HSV(((i - f /(v - x))/6), (v - x)/v, v);
}
RGBType HSV_to_RGB( HSVType HSV )
{
// H is given on [0, 1] or UNDEFINED. S and V are given on [0, 1].
// RGB are each returned on [0, 1].
float h = HSV.H * 6, s = HSV.S, v = HSV.V, m, n, f;
int i;
RGBType RGB;
if (h == 0) h=.01;
if(h == UNDEFINED) RETURN_RGB(v, v, v);
i = floorf(h);
f = h - i;
if(!(i & 1)) f = 1 - f; // if i is even
m = v * (1 - s);
n = v * (1 - s * f);
switch (i)
{
case 6:
case 0: RETURN_RGB(v, n, m);
case 1: RETURN_RGB(n, v, m);
case 2: RETURN_RGB(m, v, n);
case 3: RETURN_RGB(m, n, v);
case 4: RETURN_RGB(n, m, v);
case 5: RETURN_RGB(v, m, n);
}
RETURN_RGB(0, 0, 0);
}
//------------------
I hope somebody else finds this useful.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden