0

I used this excellent SO post to figure out how to get different shades and tints of a chosen color, but now I'm hoping to improve the algorithm. Colors in the middle range (with RGB's that add up to about 400 to 500) produce excellent results like those seen in rows 2 and 4 below. But colors outside of that range result in something more like what you see in rows 1 and 3 where the lighter colors don't fade out very much. I think I need to adjust my multiplier to correct this problem, but my math skills just aren't up to it.

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

If you want to try it out for yourself, full code is available at: http://pastebin.com/QgCseY4k

Community
  • 1
  • 1
HK1
  • 11,941
  • 14
  • 64
  • 99

3 Answers3

0

from what i know here is a way to get uniformly increasing darkness in the shade :-

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

Explanation : The brightness of color depends only on the magnitude of rgb without changing their ratio hence multiplying by factor in (0,1) gets you the color with desired brightness.

Note: What you have done works fine for generating tints from pure color.

Vikram Bhat
  • 6,106
  • 3
  • 20
  • 19
0

Here's what I ended up with. It differs from Vikram Bhat's answer in that I'm now doing two separate loops, one for shades and one for tints, and the distribution is maintained by getting a Max for my counter by taking the total RGB and dividing it by 38.25 (which is what you get if you take 765 and divide it by 20). I should have mentioned in my original post that I was looking for 20 colors as equally distributed as possible, which is what this algorithm now does. Selecting various shades of grey, white, and black, actually results in the same exact 20 colors being returned (for better or for worse).

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));
    }
}
HK1
  • 11,941
  • 14
  • 64
  • 99
0

Here is how I do it:

    /// <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);
    }
Stipo
  • 4,566
  • 1
  • 21
  • 37