使用RGB值改善色调和色调算法

时间:2014-02-18 06:19:28

标签: c# algorithm math colors

我使用this excellent SO post来弄清楚如何获得所选颜色的不同色调和色调,但现在我希望改进算法。中间范围内的颜色(RGB加起来大约为400到500)产生了如下面第2行和第4行所示的优异结果。但是,超出该范围的颜色会产生更像您在第1行和第3行中看到的颜色,其中较浅的颜色不会淡出。我想我需要调整我的乘数才能纠正这个问题,但我的数学技能却达不到它。

enter image description here

private void getShadesAndTints(Color c)
{
    int i; Double m;
    int r; int g; int b;
    for (i = 1; i < 21; i++)
    {
        m = i * 0.1;
        r = (int)(c.R * m); if (r > 255) r = 255;
        g = (int)(c.G * m); if (g > 255) g = 255;
        b = (int)(c.B * m); if (b > 255) b = 255;
        colorList.Add(Color.FromArgb(r, g, b));
    }
}

如果您想亲自尝试一下,可以在http://pastebin.com/QgCseY4k

找到完整的代码

3 个答案:

答案 0 :(得分:0)

据我所知,这是一种在阴影中均匀增加黑暗的方法: -

private void getShades(Color c)
{
    int i; Double factor;
    int r; int g; int b;
    for (i = 20; i >=0; i--)
    {
        factor = i/20;
        r = (int)(c.R * factor); if (r > 255) r = 255;
        g = (int)(c.G * factor); if (g > 255) g = 255;
        b = (int)(c.B * factor); if (b > 255) b = 255;
        colorList.Add(Color.FromArgb(r, g, b));
    }
}

说明:颜色的亮度仅取决于rgb的大小而不改变它们的比例,因此乘以(0,1)中的因子可获得所需亮度的颜色。

注意:您所做的工作可以很好地生成纯色调。

答案 1 :(得分:0)

这是我最终的结果。它与Vikram Bhat的答案不同之处在于我现在正在做两个单独的循环,一个用于阴影,一个用于色调,并且通过获取总计RGB并将其除以38.25(即如果你拿765并除以20)你会得到什么。我应该在我的原帖中提到我正在寻找尽可能均匀分布的20种颜色,这就是这个算法现在所做的。选择灰色,白色和黑色的各种色调,实际上会返回相同的20种颜色(无论好坏)。

private void getShadesAndTints(Color c)
{
    Double RGB; Double max;
    RGB = (int)c.R + (int)c.G + (int)c.B;
    max = (int)RGB / 38.25;
    max = Math.Round(max);
    if (max == 19) max = 20;
    Double i;  Double f; 
    int r; int g; int b;
    for (i = 0; i < max; i++)
    {
        f = 1 / max;
        f = i * f; 
        r = (int)(c.R * f); if (r > 255) r = 255;
        g = (int)(c.G * f); if (g > 255) g = 255;
        b = (int)(c.B * f); if (b > 255) b = 255;
        colorList.Add(Color.FromArgb(r, g, b));
    }
    max = 20 - max;
    for (i = 0; i < max; i++)
    {
        f = 1 / max;
        f = i * f;
        r = (int)((255 - c.R) * f + c.R); if (r > 255) r = 255;
        g = (int)((255 - c.G) * f + c.G); if (g > 255) g = 255;
        b = (int)((255 - c.B) * f + c.B); if (b > 255) b = 255;
        colorList.Add(Color.FromArgb(r, g, b));
    }
}

答案 2 :(得分:0)

我是这样做的:

    /// <summary>
    /// <para>Fades the specified color by the fading factor from interval [-1, 1].</para>
    /// <para>
    /// For example, -0.3 will make color 30% darker and 0.3 will make color 30% lighter.
    /// </para>
    /// </summary>
    /// <param name="color">The color.</param>
    /// <param name="fading">The fading factor.</param>
    /// <returns>The faded color.</returns>
    private static Color Fade(Color color, double fading)
    {
        Debug.Assert(fading >= -1 && fading <= 1);

        if (fading < 0)
        {
            var shade = 1 + fading;
            return Color.FromArgb(ShadeComponent(color.R, shade), ShadeComponent(color.G, shade), ShadeComponent(color.B, shade));
        }
        else if (fading > 0)
        {
            var tint = 1 - fading;
            return Color.FromArgb(TintComponent(color.R, tint), TintComponent(color.G, tint), TintComponent(color.B, tint));
        }
        else
            return color;
    }

    private static int ShadeComponent(int component, double shade)
    {
        return Round(component * shade);
    }

    private static int TintComponent(int component, double tint)
    {
        return Round(255 - (255 - component) * tint);
    }

    private static int Round(double value)
    {
        return (int)Math.Round(value);
    }