Skip navigation.
 
mlHere is code to Convert RGB <-> HSB
FROM : Duncan Champney
DATE : Mon Feb 11 21:22:51 2008

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.

Related mailsAuthorDate
mlHere is code to Convert RGB <-> HSB Duncan Champney Feb 11, 21:22
mlRe: Here is code to Convert RGB <-> HSB Nicko van Someren Feb 11, 23:11