使用的编程语言是C#和.NET 3.5。
回答评论:颜色格式为(Alpha)RGB,值为字节或浮点数。
标记答案:对于我的应用场景(一些简单的UI效果),我选择接受最简单的答案。然而,我也给了更复杂和准确的答案赞成票。未来进行更高级的颜色操作并发现这个线程的任何人都应该查看这些答案。谢谢 Stack Overflow。 :)
在XNA中有一个静态方法Color.Lerp
(了解更多),它可以计算两种颜色之间的差异。
Lerp
是介于两个浮点数之间的数学运算,通过这个运算可以按比例改变第一个浮点数的值。
下面是一个扩展方法,用于将它应用到浮点数中:
public static float Lerp( this float start, float end, float amount)
{
float difference = end - start;
float adjusted = difference * amount;
return start + adjusted;
}
那么使用RGB对两种颜色进行简单的线性插值操作如下:
public static Color Lerp(this Color colour, Color to, float amount)
{
// start colours as lerp-able floats
float sr = colour.R, sg = colour.G, sb = colour.B;
// end colours as lerp-able floats
float er = to.R, eg = to.G, eb = to.B;
// lerp the colours to get the difference
byte r = (byte) sr.Lerp(er, amount),
g = (byte) sg.Lerp(eg, amount),
b = (byte) sb.Lerp(eb, amount);
// return the new colour
return Color.FromArgb(r, g, b);
}
应用此方法的示例可能如下:
// make red 50% lighter:
Color.Red.Lerp( Color.White, 0.5f );
// make red 75% darker:
Color.Red.Lerp( Color.Black, 0.75f );
// make white 10% bluer:
Color.White.Lerp( Color.Blue, 0.1f );
return Color.FromArgb(colour.A, r, g, b);
或者 RGB 版本:return Color.FromRgb(r, g, b);
。 - Lennart将RGB值乘以您要修改的级别量即可。 如果其中一种颜色已经达到最大值,那么您无法使其更加明亮(至少使用HSV算法是这样的)。
这样做可以用更少的计算得到完全相同的结果,而不必切换到HSV然后修改V。 只要您不想开始失去饱和度,这与切换到HSL然后修改L得到相同的结果。
HSV(色相/饱和度/明度)也称为HSL(色相/饱和度/亮度),它只是一种不同的颜色表示方法。
使用此表示方法可以更轻松地调整亮度。因此,将RGB转换为HSV,增加“V”,然后再转换回RGB。
以下是一些用于转换的C代码:
void RGBToHSV(unsigned char cr, unsigned char cg, unsigned char cb,double *ph,double *ps,double *pv)
{
double r,g,b;
double max, min, delta;
/* convert RGB to [0,1] */
r = (double)cr/255.0f;
g = (double)cg/255.0f;
b = (double)cb/255.0f;
max = MAXx(r,(MAXx(g,b)));
min = MINx(r,(MINx(g,b)));
pv[0] = max;
/* Calculate saturation */
if (max != 0.0)
ps[0] = (max-min)/max;
else
ps[0] = 0.0;
if (ps[0] == 0.0)
{
ph[0] = 0.0f; //UNDEFINED;
return;
}
/* chromatic case: Saturation is not 0, so determine hue */
delta = max-min;
if (r==max)
{
ph[0] = (g-b)/delta;
}
else if (g==max)
{
ph[0] = 2.0 + (b-r)/delta;
}
else if (b==max)
{
ph[0] = 4.0 + (r-g)/delta;
}
ph[0] = ph[0] * 60.0;
if (ph[0] < 0.0)
ph[0] += 360.0;
}
void HSVToRGB(double h,double s,double v,unsigned char *pr,unsigned char *pg,unsigned char *pb)
{
int i;
double f, p, q, t;
double r,g,b;
if( s == 0 )
{
// achromatic (grey)
r = g = b = v;
}
else
{
h /= 60; // sector 0 to 5
i = (int)floor( h );
f = h - i; // factorial part of h
p = v * ( 1 - s );
q = v * ( 1 - s * f );
t = v * ( 1 - s * ( 1 - f ) );
switch( i )
{
case 0:
r = v;
g = t;
b = p;
break;
case 1:
r = q;
g = v;
b = p;
break;
case 2:
r = p;
g = v;
b = t;
break;
case 3:
r = p;
g = q;
b = v;
break;
case 4:
r = t;
g = p;
b = v;
break;
default: // case 5:
r = v;
g = p;
b = q;
break;
}
}
r*=255;
g*=255;
b*=255;
pr[0]=(unsigned char)r;
pg[0]=(unsigned char)g;
pb[0]=(unsigned char)b;
}
V=0.25
,且我需要从给定颜色开始使用 4
种较浅的色调,则 V 的值将为 0.25、0.5、0.75 和 1
?这些数字是否总是需要遵循*等差数列(AP)*? - GeekRich Newman在他的博客上讨论了HSL颜色,并针对.NET System.Drawing.Color进行了探讨,甚至提供了一个HSLColor类来为您完成所有工作。将您的System.Drawing.Color转换为HSLColor,在亮度方面添加/减去值,并将其转换回System.Drawing.Color以供在您的应用程序中使用。
你可以将颜色转换为HSL颜色空间,在那里操作并转换回您选择的颜色空间(最可能是RGB)。
较浅的颜色具有更高的L值,而较暗的颜色则具有较低的L值。
以下是相关的内容和所有方程式:
http://en.wikipedia.org/wiki/HSL_color_space
另一种方法是简单地将您的颜色与白色或黑色插值。这也会使颜色变得减淡一些,但计算成本较低。
我曾经使用过System.Windows.Forms
中的ControlPaint.Dark()
和.Light()
。
Color lighterColor = ControlPaint.Light(originalColor, 1.0f);
- Jinlyef
的取值范围为 0.0 到 1.0,则有以下公式:Rnew = (1-f)*R + f*255
Gnew = (1-f)*G + f*255
Bnew = (1-f)*B + f*255
如果要使用较暗的色调,请使用黑色的RGB值——因为它全是零,数学计算更加容易。
我省略了一些细节,比如将结果转换回字节,这可能是你想要做的。