有没有一种简单的方法来混合两个
System.Drawing.Color
值?或者我是否必须编写自己的方法来获取两种颜色并将它们组合起来?
如果我这样做,该怎么办?
我正是为此目的编写了一个实用方法。 :)
/// <summary>Blends the specified colors together.</summary>
/// <param name="color">Color to blend onto the background color.</param>
/// <param name="backColor">Color to blend the other color onto.</param>
/// <param name="amount">How much of <paramref name="color"/> to keep,
/// “on top of” <paramref name="backColor"/>.</param>
/// <returns>The blended colors.</returns>
public static Color Blend(this Color color, Color backColor, double amount)
{
byte r = (byte) (color.R * amount + backColor.R * (1 - amount));
byte g = (byte) (color.G * amount + backColor.G * (1 - amount));
byte b = (byte) (color.B * amount + backColor.B * (1 - amount));
return Color.FromRgb(r, g, b);
}
如果您想以人眼看起来更自然的方式混合颜色,您应该考虑在与 RGB 不同的颜色空间中工作,例如 L*a*b*、HSL、HSB。
有一篇很棒的关于颜色空间的代码项目文章,其中包含 C# 示例。
您可能喜欢使用 L*a*b*,因为它旨在线性化颜色差异的感知,因此应该产生优雅的渐变。
我认为混合一系列颜色更容易,以防万一你想混合超过 2 种颜色 这是我的功能:
private Color colorBlend(List<Color> clrArr)
{
int r = 0;
int g = 0;
int b = 0;
foreach(Color color in clrArr)
{
r += color.R;
g += color.G;
b += color.B;
}
r = r / clrArr.Count;
g = g / clrArr.Count;
b = b / clrArr.Count;
return Color.FromArgb(r, g, b);
}
数组必须是颜色列表 使用:
List<Color> colorList = new List<Color>();
colorList.Add(Color.Red);
colorList.Add(Color.Blue);
picturebox.backColor = colorBlend(colorList);
要通过使用 alpha 混合来组合两种颜色,可以采用以下方法:
private const float Divisor = byte.MaxValue;
public static Color AlphaBlend(this Color backColor, Color foreColor)
{
var fa = foreColor.A / Divisor;
var fr = foreColor.R / Divisor;
var fg = foreColor.G / Divisor;
var fb = foreColor.B / Divisor;
var ba = backColor.A / Divisor;
var br = backColor.R / Divisor;
var bg = backColor.G / Divisor;
var bb = backColor.B / Divisor;
var a = fa + ba - fa * ba;
if (a <= 0)
return Color.Transparent;
var r = (fa * (1 - ba) * fr + fa * ba * fa + (1 - fa) * ba * br) / a;
var g = (fa * (1 - ba) * fg + fa * ba * fa + (1 - fa) * ba * bg) / a;
var b = (fa * (1 - ba) * fb + fa * ba * fa + (1 - fa) * ba * bb) / a;
return Color.FromArgb(
(int)(a * byte.MaxValue),
(int)(r * byte.MaxValue),
(int)(g * byte.MaxValue),
(int)(b * byte.MaxValue));
}