是否有用于HSV到RGB的内置C#/ .NET系统API?

jsi*_*ght 28 .net c# colors

.NET框架中是否内置了将HSV转换为RGB的API ?我没有在System.Drawing.Color中看到一个方法,但是平台上没有一个方法似乎令人惊讶.

Gre*_*reg 51

没有内置的方法可以做到这一点,但计算并不是非常复杂.
另请注意,Color的GetHue(),GetSaturation()和GetBrightness()返回HSL值,而不是HSV.

以下C#代码使用Wikipedia上描述的算法在RGB和HSV之间进行转换.
我已经在这里发布了这个答案,但我会在这里复制代码以供快速参考.

色调范围为0 - 360,饱和度或值范围为0 - 1.

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);
}
Run Code Online (Sandbox Code Playgroud)


Pat*_*son 20

我不认为在.NET框架中有这样做的方法.
检查使用C#将HSV转换为RGB颜色

这是实现代码,

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;
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你的方法.很奇怪,Color有.GetHue(),. GetSaturation()和.GetBrightness(),但没有像.fromHSB()这样的反向方法. (6认同)
  • 为什么不返回一个 Color 对象而不是对三个单独的值使用 *out* ? (2认同)
  • @FizzledOut:也许因为这样,代码可以直接用于[SWF `Color`](https://msdn.microsoft.com/en-us/library/system.drawing.color%28v=vs.85% 29.aspx), [WPF `颜色`](https://msdn.microsoft.com/en-us/library/system.windows.media.color%28v=vs.110%29.aspx), [Gdk# `颜色`](http://docs.go-mono.com/?link=T%3aGdk.Color) 等。 (2认同)
  • 例如,如果您从 `System.Drawing.Color.FromArgb(255, 0, 0)` 开始,使用 `.GetHue()` 等将其发送到 HSV,然后使用此代码返回到 `Color` , 你得到 rgb 127, 0, 0。`.GetBrightness()` 返回 0.5,这段代码将其解释为主色是 255*.5 = 127。至少从我的角度来看,这意味着这段代码不能正常工作. (2认同)

Joe*_*ack 13

它不是内置的,但是有一个名为ColorMine的开源C#库 ,它可以很容易地在颜色空间之间进行转换.

Rgb到Hsv:

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

Hsv到Rgb:

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