褪色的正确数学是什么?

What's the correct math to fade a color?

本文关键字:是什么 褪色      更新时间:2023-10-16

我正在尝试褪色一种颜色,假设Yellow在一段时间内变为White。我已经得到了计时器的工作,我应用的新颜色也很好,但褪色是不光滑的(例如。它在到达White之前逐渐变成一些奇怪的颜色,其中一些比它们在"褪色链"上的前身更暗(我们称之为)。我确信这是因为数学是错误的,但我似乎找不到一个好的数学例子来修改我正在做的。

我甚至从这个问题中提取了ColorCeiling代码的基础知识:将颜色褪色为白色(增加亮度)

现在我取一个颜色,并调用扩展方法Increase:

dataGridViewResults.Rows[0].DefaultCellStyle.BackColor.Increase(50);
public static Color Increase(this Color color, byte offset)
{
    return Color.FromArgb(
        color.A.ColorCeiling(offset),
        color.R.ColorCeiling(offset),
        color.G.ColorCeiling(offset),
        color.B.ColorCeiling(offset));
}

,正如您所看到的,每种颜色都被偏移量修改,并考虑到一个上限,以防止抛出异常。这个扩展方法,ColorCeiling看起来像这样:

public static int ColorCeiling(this byte val, byte modifier, byte ceiling = 255)
{
    return (val + modifier > ceiling) ? ceiling : val + modifier;
}

现在,我确信ColorCeiling是问题所在,但老实说,我就是找不到数学。老实说,我觉得只是增加ARGB几乎肯定是错误的方法,似乎你会说我想让你轻50%,但我只是不知道这意味着什么,只要代码。

这里有一个可能可行的主意。

不要在红绿蓝空间做数学计算。相反,把你的颜色分成三个部分:

  • 色相(红色、橙色、黄色、绿色、蓝色、紫色等),
  • 饱和度(颜色有多浓?)
  • 值(颜色中有多少黑度?)

有从RGB到HSV的转换算法;查一下。这是一个很好的开始:

http://en.wikipedia.org/wiki/HSL_and_HSV

现在,当你从一种颜色褪色到另一种颜色时,沿着HSV轴采取步骤,而不是沿着RGB轴。

渐变就是你要找的。你必须把它们分开,然后像这样重新组合。

int rMax = Color.Yellow.R;
int rMin = Color.White.R;
int bMax = Color.Yellow.B;
int bMin = Color.White.B;
int gMax = Color.Yellow.G;
int gMin = Color.White.G;
var colorList = new List<Color>();
for(int i=0; i<size; i++)
{
    var rAverage = rMin + (int)((rMax - rMin) * i / size);
    var bAverage = bMin + (int)((bMax - bMin) * i / size);
    var gAverage = gMin + (int)((gMax - gMin) * i / size);
    colorList.Add(Color.FromArgb(rAverage, gAverage, bAverage));
}

Percentage表示乘法,而不是加法。在我非常简单的JavaScript Color类中,我通过定义两种颜色并混合RGB尺寸来完成这种事情。

From my Color class:

this.getBlendedColor = function(color, percent) {
    // limit percent between 0 and 1.
    // this percent is the amount of 'color' rgb components to use
    var p = percent > 0 ? percent : 0;
    p = p < 1 ? p : 1;
    // amount of 'this' rgb components to use
    var tp = 1 - p;
    // blend the colors
    var r = Math.round(tp * this.r + p * color.r);
    var g = Math.round(tp * this.g + p * color.g);
    var b = Math.round(tp * this.b + p * color.b);
    // return new color object
    return new Color(r, g, b);
} // getBlendedColor ()

如果你有一个颜色c,你想让它变白50%,你可以这样做:

var newColor = c.getBlendedColor(new Color('#ffffff'), 0.50);

如果你正在使用alpha通道,它可以显式地包含,而不会造成任何麻烦——在你的例子中,两种颜色都可能是100%的不透明度。

使用简单RGB颜色混合数学的渐变示例:http://jsfiddle.net/2MymY/1/

下面是我用来在RGB色彩空间中从一种颜色渐变到另一种颜色的一些代码。它很适合我的目的。您可能需要调整它以逐步返回颜色。目前,对于每个i,您将有一个curClr, baseClrfadeTo之间的 i/discreteUnits%。

int discreteUnits = 10;
Color fadeTo = Color.Green;
Color baseClr = Color.Red;
float correctionFactor = 0.0f;
float corFactorStep = 1.0f / discreteUnits;
for(int i = 0; i < discreteUnits; i++)
{
    correctionFactor += corFactorStep;
    float red = (fadeTo.R - baseClr.R) * correctionFactor + baseClr.R;
    float green = (fadeTo.G - baseClr.G) * correctionFactor + baseClr.G;
    float blue = (fadeTo.B - baseClr.B) * correctionFactor + baseClr.B;
    Color curClr = Color.FromArgb(baseClr.A, (int)red, (int)green, (int)blue);
}

感谢这个网站给了我一个起点:http://www.pvladov.com/2012/09/make-color-lighter-or-darker.html