如何确定给定颜色的较暗或较浅的颜色变体?

给定系统或用户对任何色调的源颜色,我想用一个简单的算法来计算出所选颜色的较亮或较暗的变体。 类似于Windows Live Messenger上用于设计用户界面风格的效果。

语言是C#与.net 3.5。

回应评论:彩色格式是(Alpha)RGB。 值为字节或浮点数。

标记答案:对于我使用的上下文(几个简单的UI效果),我标记为接受的答案实际上是对于该上下文最简单的答案。 但是,我已经放弃了对更复杂和准确答案的投票。 任何人进行更高级的颜色操作并在未来找到这个线程都应该检查这些。 感谢所以。 :)


只需将RGB值乘以您想要修改的值即可。 如果其中一种颜色已经达到最大值,那么你就无法使它变得更亮(反正使用HSV数学)。

这就给出了完全相同的结果,其中切换到HSV然后修改V得到了相同的结果。只要您不想开始失去饱和度,就会得到与切换到HSL然后修改L相同的结果。


在XNA中有Color.Lerp静态方法,它将这作为两种颜色之间的差异。

Lerp是两个浮点数之间的数学运算,它们通过它们之间的差异比改变第一个浮点数的值。

下面是一个扩展方法将其尽到一个float

public static float Lerp( this float start, float end, float amount)
{
    float difference = end - start;
    float adjusted = difference * amount;
    return start + adjusted;
}

因此,使用RGB的两种颜色之间的简单的lerp操作将是:

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 );

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;
}
链接地址: http://www.djcxy.com/p/87399.html

上一篇: How do I determine darker or lighter color variant of a given color?

下一篇: C#: Create a lighter/darker color based on a system color