2009-08-26 28 views

回答

17

我不認爲在.NET框架中有這樣做的方法。
退房Converting HSV to RGB colour using C#

這是實現代碼,

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

感謝您的方法。奇怪的顏色有.GetHue(),.GetSaturation()和.GetBrightness(),但沒有反例如.fromHSB()。 – MusiGenesis 2009-08-26 15:23:04

+0

確實......它是一個非常奇怪的遺漏,伊莫。 – jsight 2009-08-26 15:27:13

+0

爲什麼不返回一個Color對象而不是使用* out *作爲三個單獨的值? – 2014-06-14 13:52:42

48

沒有這樣做的一個內置的方法,但計算並不十分複雜。
還要注意的是顏色的GetHue(),GetSaturation()和GetBrightness()的返回值HSL,HSV沒有。

以下C#代碼RGB和HSV之間轉換使用上Wikipedia描述的算法。
我已經張貼了這個答案here,但我會在這裏複製的代碼爲快速參考。

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

您的ColorFromHSV可能有問題,我試圖用相反顏色的代碼旋轉180度的色相,但效果不佳。接受的代碼給出了一種不同的顏色,這對我來說似乎是正確的 – 2016-01-21 20:30:06

+0

但是,我正在使用ColorToHSV功能。它似乎運作良好。 – 2016-01-21 20:31:08

+0

@IsaacBolinger不與負色調很好地工作,以及workd色相> = 0,但在較好的代碼中使用<0,360)之間的色調。 – xmedeko 2017-10-19 08:26:12

-1

http://richnewman.wordpress.com/hslcolor-class/具有優異的C#類,以提供所有必要的轉換,包括向和從窗口系統顏色。

+0

問題是HSB/V,而不是HSL,經常混淆。實際上,微軟自己通過將Color.GetBrightness()引用爲HSB而得到了錯誤的結果,實際上它是HSL。 – redshift5 2015-12-02 08:44:30

12

這不是內置的,但有有一個名爲ColorMine一個開源C#庫,這使得色彩空間很容易之間的轉換。

RGB到HSV:

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

胸苷到RGB:

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