71

如何使用 C# 将 RGB 颜色转换为 HSV?
我在不使用任何外部库的情况下搜索了一种快速方法。

4

7 回答 7

114

请注意Color.GetSaturation()Color.GetBrightness()返回 HSL 值,而不是 HSV。
下面的代码演示了不同之处。

Color original = Color.FromArgb(50, 120, 200);
// original = {Name=ff3278c8, ARGB=(255, 50, 120, 200)}

double hue;
double saturation;
double value;
ColorToHSV(original, out hue, out saturation, out value);
// hue        = 212.0
// saturation = 0.75
// value      = 0.78431372549019607

Color copy = ColorFromHSV(hue, saturation, value);
// copy = {Name=ff3278c8, ARGB=(255, 50, 120, 200)}

// Compare that to the HSL values that the .NET framework provides: 
original.GetHue();        // 212.0
original.GetSaturation(); // 0.6
original.GetBrightness(); // 0.490196079

以下 C# 代码是您想要的。它使用Wikipedia上描述的算法在 RGB 和 HSV 之间进行转换。范围为 0 - 360hue和 0 - 1 为saturationor value

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);
}
于 2009-10-26T17:34:29.300 回答
26

您是否考虑过简单地使用 System.Drawing 命名空间?例如:

System.Drawing.Color color = System.Drawing.Color.FromArgb(red, green, blue);
float hue = color.GetHue();
float saturation = color.GetSaturation();
float lightness = color.GetBrightness();

请注意,这并不完全符合您的要求(请参阅HSL 和 HSV 之间的差异,并且 Color 类没有从 HSL/HSV 转换回来,但后者相当容易添加.

于 2009-03-12T01:07:59.757 回答
6

这里有一个 C 实现:

http://www.cs.rit.edu/~ncs/color/t_convert.html

转换为 C# 应该非常简单,因为几乎没有调用任何函数 - 只是计算。

通过谷歌找到

于 2008-12-11T14:57:43.963 回答
6

EasyRGB许多色彩空间转换。这是RGB->HSV 转换的代码。

于 2012-10-09T21:45:58.197 回答
3

这是从 BlaM 帖子中的 C 代码移植的 VB.net 版本,对我来说效果很好。

这里有一个 C 实现:

http://www.cs.rit.edu/~ncs/color/t_convert.html

转换为 C# 应该非常简单,因为几乎没有调用任何函数 - 只是 > 计算。


Public Sub HSVtoRGB(ByRef r As Double, ByRef g As Double, ByRef b As Double, ByVal h As Double, ByVal s As Double, ByVal v As Double)
    Dim i As Integer
    Dim f, p, q, t As Double

    If (s = 0) Then
        ' achromatic (grey)
        r = v
        g = v
        b = v
        Exit Sub
    End If

    h /= 60 'sector 0 to 5
    i = Math.Floor(h)
    f = h - i 'factorial part of h
    p = v * (1 - s)
    q = v * (1 - s * f)
    t = v * (1 - s * (1 - f))

    Select Case (i)
        Case 0
            r = v
            g = t
            b = p
            Exit Select
        Case 1
            r = q
            g = v
            b = p
            Exit Select
        Case 2
            r = p
            g = v
            b = t
            Exit Select
        Case 3
            r = p
            g = q
            b = v
            Exit Select
        Case 4
            r = t
            g = p
            b = v
            Exit Select
        Case Else   'case 5:
            r = v
            g = p
            b = q
            Exit Select
    End Select
End Sub
于 2009-07-27T10:51:28.810 回答
0

I've ended up here by having the same need.

Bellow I'm sharing the best and simpler solution I could find so far.
This is a modified answer from Greg's (found here); but with a humbler and understandable code.

For those who are learning I've added a few references that are worth checking for the sake of understanding.


References

  1. "Lukas Stratmann" HSV Model Tool (Incl. Other Model Systems: CMY / CMYK / HSL)
  2. "The HSV Color Model in Graphic Design"
  3. "Formula to Determine Perceived Brightness of RGB Color"
  4. Fastest Formula to Get Hue from RGB
  5. "Color Conversion Algorithms"
  6. "Program to Change RGB color model to HSV color model"
  7. "RGB to HSV Color Conversion Algorithm"
  8. "RGB to HSV Color Space Conversion (C)"
  9. "How to Convert RGB Color to HSV"

Code

    /// <summary> Convert RGB Color to HSV. </summary>
    /// <param name="color"></param>
    /// <returns> A double[] Containing HSV Color Values. </returns>
    public double[] rgbToHSV(Color color)
    {
        double[] output = new double[3];

        double hue, saturation, 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;

        output[0] = hue;
        output[1] = saturation;
        output[2] = value;

        return output;
    }
于 2021-10-28T19:32:20.753 回答
-1

第一:确保你有一个颜色作为位图,像这样:

Bitmap bmp = (Bitmap)pictureBox1.Image.Clone();
paintcolor = bmp.GetPixel(e.X, e.Y);

(e 来自事件处理程序,它选择了我的颜色!)

What I did when I had this problem a whilke ago, I first got the rgba (red, green, blue and alpha) values. Next I created 3 floats: float hue, float saturation, float brightness. Then you simply do:

hue = yourcolor.Gethue;
saturation = yourcolor.GetSaturation;
brightness = yourcolor.GetBrightness;

The whole lot looks like this:

Bitmap bmp = (Bitmap)pictureBox1.Image.Clone();
            paintcolor = bmp.GetPixel(e.X, e.Y);
            float hue;
            float saturation;
            float brightness;
            hue = paintcolor.GetHue();
            saturation = paintcolor.GetSaturation();
            brightness = paintcolor.GetBrightness();

If you now want to display them in a label, just do:

yourlabelname.Text = hue.ToString;
yourlabelname.Text = saturation.ToString;
yourlabelname.Text = brightness.ToString;

Here you go, you now have RGB Values into HSV values :)

Hope this helps

于 2016-07-02T11:34:42.987 回答