【问题标题】:C# setHue (or alternatively, convert HSL to RGB and set RGB)C# setHue(或者,将 HSL 转换为 RGB 并设置 RGB)
【发布时间】:2015-04-29 20:26:44
【问题描述】:

C#有一个很方便的getHue方法,但是我找不到setHue方法。有吗?

如果不是,我认为在更改色调后定义颜色的最佳方法是将 HSL 值转换为 RGB,然后设置 RGB 值。我知道互联网上有执行此操作的公式,但我将如何最好地使用 C# 执行从 HSL 到 RGB 的转换?

谢谢

【问题讨论】:

标签: c# colors rgb hsl


【解决方案1】:

要设置色相,您可以使用GetHueGetSaturation 从给定的Color 创建一个新的@。 getBrightness 函数见下文!

我正在使用这个:

Color SetHue(Color oldColor)
{
    var temp = new HSV();
    temp.h = oldColor.GetHue();
    temp.s = oldColor.GetSaturation();
    temp.v = getBrightness(oldColor);
    return ColorFromHSL(temp);
}

// A common triple float struct for both HSL & HSV
// Actually this should be immutable and have a nice constructor!!
public struct HSV { public float h; public float s; public float v;}

// the Color Converter
static public Color ColorFromHSL(HSV hsl)
{
    if (hsl.s == 0)
    { int L = (int)hsl.v; return Color.FromArgb(255, L, L, L); }

    double min, max, h;
    h = hsl.h / 360d;

    max = hsl.v < 0.5d ? hsl.v * (1 + hsl.s) : (hsl.v + hsl.s) - (hsl.v * hsl.s);
    min = (hsl.v * 2d) - max;

    Color c = Color.FromArgb(255, (int)(255 * RGBChannelFromHue(min, max,h + 1 / 3d)),
                                  (int)(255 * RGBChannelFromHue(min, max,h)), 
                                  (int)(255 * RGBChannelFromHue(min, max,h - 1 / 3d)));
    return c;
}

static double RGBChannelFromHue(double m1, double m2, double h)
{
    h = (h + 1d) % 1d;
    if (h < 0) h += 1;
    if (h * 6 < 1) return m1 + (m2 - m1) * 6 * h;
    else if (h * 2 < 1) return m2;
    else if (h * 3 < 2) return m1 + (m2 - m1) * 6 * (2d / 3d - h);
    else return m1;

}

不要使用内置的GetBrightness 方法!它为红色、品红色、青色、蓝色和黄色 (!) 返回相同的值 (0.5f)。这样更好:

// color brightness as perceived:
float getBrightness(Color c)  
   {  return (c.R * 0.299f + c.G * 0.587f + c.B *0.114f) / 256f; }

【讨论】:

    【解决方案2】:

    System.Drawing.Color 是一种值类型,它几乎总是不可变的,尤其是在框架中。这就是为什么你不能在上面setHue,你只能用你需要的字段构造一个新的值类型。

    所以,如果你有一个函数可以为你的 HSB 值提供 RGB 值,你可以这样做

    Color oldColor = ...;
    int red, green, blue;
    FromHSB(oldColor.GetHue(), oldColor.GetSaturation(), oldColor.GetBrightness(), out red, out green out blue);
    Color newColor = Color.FromArgb(oldColor.A, red, green, blue);
    

    FromHSB 看起来像这样

    void FromHSB(float hue, float saturation, float brightness, out int red, out int green, out int blue)
    {
        // ...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-29
      • 1970-01-01
      • 2016-08-11
      • 1970-01-01
      • 2011-01-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多