2009-08-26 5 views

Antwort

17

Ich glaube nicht, dass es eine Methode im .NET Framework gibt. out
prüfen Converting HSV to RGB colour using C#

Dies ist der Implementierungscode,

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

Dank für diese Methode. Seltsam, dass Color .GetHue(), .GetSaturation() und .GetBrightness() hat, aber keine inverse Methode wie .fromHSB(). – MusiGenesis

+0

In der Tat ... es ist eine sehr seltsame Unterlassung, imo. – jsight

+0

Warum nicht ein Color-Objekt anstelle von * out * für drei separate Werte zurückgeben? –

48

Es gibt keine integrierte Methode, dies zu tun, aber die Berechnungen sind nicht sehr komplex.
Beachten Sie auch, dass Color GetHue(), GetSaturation() und GetBrightness() HSL-Werte, nicht HSV zurückgeben.

Der folgende C# -Code konvertiert zwischen RGB und HSV mit den unter Wikipedia beschriebenen Algorithmen.
Ich habe diese Antwort bereits here geschrieben, aber ich werde den Code hier für eine schnelle Referenz kopieren.

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

Ihr ColorFromHSV könnte etwas falsch gemacht haben, ich habe versucht, den Farbton um 180 Grad mit Ihrem Code für eine entgegengesetzte Farbe zu drehen, und es funktioniert nicht so gut. Der akzeptierte Code gibt eine andere Farbe, die mir richtig erscheint. –

+0

Ich verwende jedoch Ihre ColorToHSV-Funktion. Es scheint gut zu funktionieren. –

+0

@IsaacBolinger funktioniert nicht gut mit negativem Farbton, funktioniert gut für Farbton> = 0, aber besser, um Farbton zwischen <0, 360) in Ihrem Code zu verwenden. – xmedeko

-1

Blick auf http://richnewman.wordpress.com/hslcolor-class/, die eine ausgezeichnete C# -Klasse verfügt über alle notwendigen Konvertierungen zur Verfügung zu stellen, einschließlich vom und zum Windows-System Farben.

+0

Die Frage ist für HSB/V, nicht HSL, die oft durcheinander ist. Tatsächlich hat Microsoft es selbst falsch verstanden, indem es Color.GetBrightness() als HSB bezeichnet, wo es tatsächlich HSL ist. – redshift5

12

Es ist nicht eingebaut, aber es gibt eine Open-Source-C# -Bibliothek namens ColorMine, die das Konvertieren zwischen Farbräumen ziemlich einfach macht.

Rgb zu Hsv:

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

Hsv zu Rgb:

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