C#有一个非常方便的getHue方法,但我找不到 set Hue方法。有吗?
如果没有,我认为更改色调后定义颜色的最佳方法是将HSL值转换为RGB,然后设置RGB值。我知道互联网上有公式可以做到这一点,但我怎样才能最好地使用C#执行从HSL到RGB的转换?
谢谢
答案 0 :(得分:1)
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)
{
// ...
}
答案 1 :(得分:1)
要设置Hue,您可以使用Color
和GetHue
创建一个新的GetSaturation
,可能来自给定的一个。请参阅下面的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; }