2009-08-26 6 views

Répondre

17

Je ne pense pas qu'il existe une méthode faisant cela dans le framework .NET.
Découvrez Converting HSV to RGB colour using C#

Voici le code de mise en œuvre,

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

Merci pour cette méthode. Bizarre que Color ait .GetHue(), .GetSaturation() et .GetBrightness(), mais pas de méthode inverse comme .fromHSB(). – MusiGenesis

+0

En effet ... c'est une omission très étrange, imo. – jsight

+0

Pourquoi ne pas retourner un objet Color au lieu d'utiliser * out * pour trois valeurs séparées? –

48

Il n'y a pas une méthode intégrée pour ce faire, mais les calculs ne sont pas très complexes.
Notez également que Color GetHue(), GetSaturation() et GetBrightness() retournent des valeurs HSL, pas HSV.

Le code C# suivant convertit entre RGB et HSV en utilisant les algorithmes décrits au Wikipedia.
J'ai déjà posté cette réponse here, mais je vais copier le code ici pour référence rapide.

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

Votre ColorFromHSV peut avoir quelque chose qui ne va pas, j'essayais de faire pivoter la teinte de 180 degrés en utilisant votre code pour une couleur opposée et ça ne fonctionne pas très bien. Le code accepté donne une couleur différente qui me semble correcte. –

+0

J'utilise votre fonction ColorToHSV, cependant. Cela semble bien fonctionner. –

+0

@IsaacBolinger ne fonctionne pas bien avec la teinte négative, bien travaillé pour hue> = 0, mais mieux d'utiliser la teinte entre <0, 360) dans votre code. – xmedeko

-1

Regardez http://richnewman.wordpress.com/hslcolor-class/ qui a une excellente C# classe pour fournir toutes les conversions nécessaires, y compris et à des fenêtres couleurs du système.

+0

La question est pour HSB/V, pas HSL, qui est souvent mélangé. En fait, Microsoft lui-même l'a mal compris en désignant Color.GetBrightness() par HSB, alors qu'en réalité il s'agit de HSL. – redshift5

12

Il n'est pas intégré, mais il existe une bibliothèque C# open source appelée ColorMine qui facilite grandement la conversion entre les espaces colorimétriques.

Rvb à Hsv:

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

Hsv rgb:

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