2009-08-26 7 views

Odpowiedz

17

Nie sądzę, istnieje metoda to zrobić w systemie .NET Framework.
Wyjazd Converting HSV to RGB colour using C#

Jest to kod wdrażania,

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

Dzięki za tą metodą. Dziwne, że Kolor ma .GetHue(), .GetSaturation() i .GetBrightness(), ale nie ma odwrotnej metody jak .fromHSB(). – MusiGenesis

+0

Rzeczywiście ... to bardzo dziwne pominięcie, imo. – jsight

+0

Dlaczego nie zwrócić obiektu Color zamiast używać * out * dla trzech oddzielnych wartości? –

48

Nie ma wbudowany sposób to zrobić, ale obliczenia nie są zbyt skomplikowane.
Należy również zauważyć, że metody GetHue(), GetSaturation() i GetBrightness() w Color zwracają wartości HSL, a nie HSV.

Następujący kod C# konwertuje między RGB i HSV za pomocą algorytmów opisanych na Wikipedia.
Już wysłałem tę odpowiedź here, ale skopiuję tutaj kod, aby uzyskać szybki dostęp.

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

Twój ColorFromHSV może mieć z tym coś nie tak, starałem się obrócić odcień o 180 stopni używając kodu dla przeciwnego koloru i to nie działa zbyt dobrze. Przyjęty kod nadaje inny kolor, który wydaje mi się poprawny. –

+0

Używam jednak funkcji ColorToHSV. Wygląda na to, że działa dobrze. –

+0

@IsaacBolinger nie działa dobrze z negatywnym odcieniem, dobrze pracował dla hue> = 0, ale lepiej używać odcienia pomiędzy <0, 360) w kodzie. – xmedeko

-1

Spójrz na http://richnewman.wordpress.com/hslcolor-class/ który posiada doskonałą C# klasy, aby zapewnić wszystkie niezbędne konwersje w tym do iz kolorów systemu Windows.

+0

Pytanie dotyczy HSB/V, a nie HSL, które często jest pomieszane. W rzeczywistości Microsoft sam zrobił to nieprawidłowo, nazywając Color.GetBrightness() HSB, gdzie w rzeczywistości jest HSL. – redshift5

12

Nie jest wbudowany, ale istnieje biblioteka C# o nazwie open source, o nazwie ColorMine, która ułatwia konwersję między przestrzeniami kolorów.

RGB na HSV:

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

HSV na RGB:

var hsv = new Hsv { H = 360, S = .5, L = .17 } 
var rgb = hsv.to<Rgb>(); 
Powiązane problemy