2009-08-26 15 views

Respuesta

17

No creo que haya un método que haga esto en .NET Framework.
Salida Converting HSV to RGB colour using C#

Este es el código de la aplicación,

void HsvToRgb(double h, double S, double V, out int r, out int g, out int b) 
{  
    double H = h; 
    while (H < 0) { H += 360; }; 
    while (H >= 360) { H -= 360; }; 
    double R, G, B; 
    if (V <= 0) 
    { R = G = B = 0; } 
    else if (S <= 0) 
    { 
    R = G = B = V; 
    } 
    else 
    { 
    double hf = H/60.0; 
    int i = (int)Math.Floor(hf); 
    double f = hf - i; 
    double pv = V * (1 - S); 
    double qv = V * (1 - S * f); 
    double tv = V * (1 - S * (1 - f)); 
    switch (i) 
    { 

     // Red is the dominant color 

     case 0: 
     R = V; 
     G = tv; 
     B = pv; 
     break; 

     // Green is the dominant color 

     case 1: 
     R = qv; 
     G = V; 
     B = pv; 
     break; 
     case 2: 
     R = pv; 
     G = V; 
     B = tv; 
     break; 

     // Blue is the dominant color 

     case 3: 
     R = pv; 
     G = qv; 
     B = V; 
     break; 
     case 4: 
     R = tv; 
     G = pv; 
     B = V; 
     break; 

     // Red is the dominant color 

     case 5: 
     R = V; 
     G = pv; 
     B = qv; 
     break; 

     // Just in case we overshoot on our math by a little, we put these here. Since its a switch it won't slow us down at all to put these here. 

     case 6: 
     R = V; 
     G = tv; 
     B = pv; 
     break; 
     case -1: 
     R = V; 
     G = pv; 
     B = qv; 
     break; 

     // The color is not defined, we should throw an error. 

     default: 
     //LFATAL("i Value error in Pixel conversion, Value is %d", i); 
     R = G = B = V; // Just pretend its black/white 
     break; 
    } 
    } 
    r = Clamp((int)(R * 255.0)); 
    g = Clamp((int)(G * 255.0)); 
    b = Clamp((int)(B * 255.0)); 
} 

/// <summary> 
/// Clamp a value to 0-255 
/// </summary> 
int Clamp(int i) 
{ 
    if (i < 0) return 0; 
    if (i > 255) return 255; 
    return i; 
} 
+6

Gracias por ese método. Es extraño que Color tenga .GetHue(), .GetSaturation() y .GetBrightness(), pero no método inverso como .fromHSB(). – MusiGenesis

+0

De hecho ... es una omisión muy extraña, imo. – jsight

+0

¿Por qué no devuelve un objeto Color en lugar de usar * out * para tres valores separados? –

48

No hay un método integrado para hacer esto, pero los cálculos no son muy complejas.
También tenga en cuenta que Color's GetHue(), GetSaturation() y GetBrightness() devuelven valores HSL, no HSV.

El siguiente código C# se convierte entre RGB y HSV utilizando los algoritmos descritos en Wikipedia.
Ya he publicado esta respuesta here, pero copiaré el código aquí para una referencia rápida.

public static void ColorToHSV(Color color, out double hue, out double saturation, out double value) 
{ 
    int max = Math.Max(color.R, Math.Max(color.G, color.B)); 
    int min = Math.Min(color.R, Math.Min(color.G, color.B)); 

    hue = color.GetHue(); 
    saturation = (max == 0) ? 0 : 1d - (1d * min/max); 
    value = max/255d; 
} 

public static Color ColorFromHSV(double hue, double saturation, double value) 
{ 
    int hi = Convert.ToInt32(Math.Floor(hue/60)) % 6; 
    double f = hue/60 - Math.Floor(hue/60); 

    value = value * 255; 
    int v = Convert.ToInt32(value); 
    int p = Convert.ToInt32(value * (1 - saturation)); 
    int q = Convert.ToInt32(value * (1 - f * saturation)); 
    int t = Convert.ToInt32(value * (1 - (1 - f) * saturation)); 

    if (hi == 0) 
     return Color.FromArgb(255, v, t, p); 
    else if (hi == 1) 
     return Color.FromArgb(255, q, v, p); 
    else if (hi == 2) 
     return Color.FromArgb(255, p, v, t); 
    else if (hi == 3) 
     return Color.FromArgb(255, p, q, v); 
    else if (hi == 4) 
     return Color.FromArgb(255, t, p, v); 
    else 
     return Color.FromArgb(255, v, p, q); 
} 
+0

Puede que su ColorFromHSV tenga algún problema. Intenté rotar el tono 180 grados utilizando su código para un color opuesto y no está funcionando demasiado bien. El código aceptado da un color diferente que me parece correcto. –

+0

Estoy usando su función ColorToHSV, sin embargo. Parece que funciona bien. –

+0

@IsaacBolinger no funciona bien con matiz negativo, funciona bien para hue> = 0, pero es mejor usar tono entre <0, 360) en su código. – xmedeko

-1

Mira http://richnewman.wordpress.com/hslcolor-class/ que tiene una excelente clase C# para proporcionar todas las conversiones necesarias, incluyendo desde y hacia los colores del sistema de Windows.

+0

La pregunta es para HSB/V, no HSL, que a menudo está mezclado. De hecho, los mismos Microsoft lo han obtenido incorrectamente al recomendar que Color.GetBrightness() sea HSB, donde de hecho es HSL. – redshift5

12

No está incorporado, pero hay una biblioteca de código abierto C# llamada ColorMine que hace que la conversión entre espacios de color sea bastante fácil.

Rgb al HSV:

var rgb = new Rgb {R = 123, G = 11, B = 7}; 
var hsv = rgb.To<Hsv>(); 

HSV a RGB:

var hsv = new Hsv { H = 360, S = .5, L = .17 } 
var rgb = hsv.to<Rgb>(); 
Cuestiones relacionadas