【发布时间】:2010-11-23 01:18:00
【问题描述】:
.NET 框架中是否有内置于converting HSV to RGB 的 API?我在 System.Drawing.Color 中没有看到用于此的方法,但平台中没有方法似乎令人惊讶。
【问题讨论】:
.NET 框架中是否有内置于converting HSV to RGB 的 API?我在 System.Drawing.Color 中没有看到用于此的方法,但平台中没有方法似乎令人惊讶。
【问题讨论】:
没有执行此操作的内置方法,但计算并不是非常复杂。
另请注意,Color 的 GetHue()、GetSaturation() 和 GetBrightness() 返回 HSL 值,而不是 HSV。
以下 C# 代码使用Wikipedia 中描述的算法在 RGB 和 HSV 之间进行转换。
我已经发布了这个答案here,但我会在这里复制代码以供快速参考。
色调的范围是 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);
}
【讨论】:
hue = (color.GetHue() + 180) % 360
我认为 .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;
}
【讨论】:
Color、WPF Color、Gdk# Color等。
System.Drawing.Color.FromArgb(255, 0, 0) 开头,使用 .GetHue() 等将其发送到 HSV,然后使用此代码往返返回到 Color,您将获得 rgb 127、0、 0..GetBrightness() 返回 0.5,这段代码解释为表示主色是 255*.5 = 127。至少从我的角度来看,这意味着这段代码不能正常工作。
它不是内置的,但有一个名为 ColorMine 的开源 C# 库,它可以很容易地在颜色空间之间进行转换。
RGB 转 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>();
【讨论】:
为此,您可以使用ColorHelper 库:
RGB rgb = ColorConverter.HsvToRgb(new HSV(100, 100, 100));
【讨论】: