devuxer
devuxer

Reputation: 42374

Does the .NET Framework 3.5 have an HsbToRgb converter or do I need to roll my own?

I did a search for an HsbToRgb converter in the docs but didn't find anything containing "hsb" or "hsl", so I'm guessing it just doesn't exist. Just to make sure, though, are there any classes that support this conversion?

Update

I ended up going with this, which is slightly different than 0xA3's. I also added an AhsbToArgb so I can convert to RGB and set the alpha channel in one shot.

AhsbToArgb - allows for alpha channel:

public static Color AhsbToArgb(byte a, double h, double s, double b)
{
    var color = HsbToRgb(h, s, b);
    return Color.FromArgb(a, color.R, color.G, color.B);
}

HsbToRgb - converts hue-saturation-brightness to red-green-blue:

public static Color HsbToRgb(double h, double s, double b)
{
    if (s == 0)
        return RawRgbToRgb(b, b, b);
    else
    {
        var sector = h / 60;
        var sectorNumber = (int)Math.Truncate(sector);
        var sectorFraction = sector - sectorNumber;
        var b1 = b * (1 - s);
        var b2 = b * (1 - s * sectorFraction);
        var b3 = b * (1 - s * (1 - sectorFraction));
        switch (sectorNumber)
        {
            case 0:
                return RawRgbToRgb(b, b3, b1);
            case 1:
                return RawRgbToRgb(b2, b, b1);
            case 2:
                return RawRgbToRgb(b1, b, b3);
            case 3:
                return RawRgbToRgb(b1, b2, b);
            case 4:
                return RawRgbToRgb(b3, b1, b);
            case 5:
                return RawRgbToRgb(b, b1, b2);
            default:
                throw new ArgumentException("Hue must be between 0 and 360");
        }
    }
}

RawRgbToRgb - converts doubles to ints and returns a color object:

private static Color RawRgbToRgb(double rawR, double rawG, double rawB)
{
    return Color.FromArgb(
        (int)Math.Round(rawR * 255),
        (int)Math.Round(rawG * 255),
        (int)Math.Round(rawB * 255));
}

Upvotes: 12

Views: 707

Answers (2)

Dirk Vollmar
Dirk Vollmar

Reputation: 176229

No it does not as far as I know. But the algorithm is not very complicated and you will find working code on the Web such as the one on this CodeProject article on Manipulating colors in .NET by Guillaume Leparmentier:

public static Color HSBtoRGB(double hue, double saturation, double brightness)
{
    double r = 0;
    double g = 0;
    double b = 0;

    if (saturation == 0)
    {
        r = g = b = brightness;
    }
    else
    {
        // The color wheel consists of 6 sectors. 
        // Figure out which sector you're in.
        //
        double sectorPos = hue / 60.0;
        int sectorNumber = (int)(Math.Floor(sectorPos));

        // get the fractional part of the sector
        double fractionalSector = sectorPos - sectorNumber;

        // calculate values for the three axes of the color. 
        double p = brightness * (1.0 - saturation);
        double q = brightness * (1.0 - (saturation * fractionalSector));
        double t = brightness * (1.0 - (saturation * (1 - fractionalSector)));

        // assign the fractional colors to r, g, and b 
        // based on the sector the angle is in.
        switch (sectorNumber)
        {
            case 0:
                r = brightness;
                g = t;
                b = p;
                break;
            case 1:
                r = q;
                g = brightness;
                b = p;
                break;
            case 2:
                r = p;
                g = brightness;
                b = t;
                break;
            case 3:
                r = p;
                g = q;
                b = brightness;
                break;
            case 4:
                r = t;
                g = p;
                b = brightness;
                break;
            case 5:
                r = brightness;
                g = p;
                b = q;
                break;
        }
    }

    return Color.FromArgb(
        (int)(r * 255.0 + 0.5), 
        (int)(g * 255.0 + 0.5), 
        (int)(b * 255.0 + 0.5));
}

Upvotes: 14

MusiGenesis
MusiGenesis

Reputation: 75366

No, in .NET (up to and including 4.0) the Color class only converts automatically from RGB to HSB (via the GetHue, GetSaturation and GetBrightness methods). You have to roll your own method to go from HSB values to RGB values, or use an already-written example, like:

http://www.codeproject.com/KB/GDI-plus/HSBColorClass.aspx

Upvotes: 5

Related Questions