褪色的正确数学是什么?
What's the correct math to fade a color?
我正在尝试褪色一种颜色,假设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
, baseClr
和fadeTo
之间的 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
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- C++避免重复声明的语法是什么
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++从另一个类访问公共静态向量的正确方法是什么
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- C++中名称篡改的目的是什么
- 在 c++ 中拥有一组结构的正确方法是什么?
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 是什么阻止DOMTimerCoordinator::NextID进入无休止的循环
- 派生类销毁的最佳实践是什么
- 这个语法std::class<>{}(arg1, arg2) 在C++中是什么意思?
- 通过JNI传递数据数组的最快方法是什么
- "using namespace std;"在C++的作用是什么?
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- 文件系统:复制功能的速度秘诀是什么
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 使用QQuickFramebufferObject时同步数据的最佳方式是什么
- 是什么原因导致它无法编译?它是声明签名还是在函数本身的实现中
- 褪色的正确数学是什么?