Given a source color of any hue by the system or user, I'd like a simple algorithm I can use to work out a lighter or darker variants of the selected color. Similar to effects used on Windows Live Messenger for styling the user interface.
Language is C# with .net 3.5.
Responding to comment: Color format is (Alpha)RGB. With values as bytes or floats.
Marking answer: For the context of my use (a few simple UI effects), the answer I'm marking as accepted is actually the most simple for this context. However, I've given up votes to the more complex and accurate answers too. Anyone doing more advanced color operations and finding this thread in future should definitely check those out. Thanks SO. :)
Value is the measurement of the amount of black or white mixed into a pure hue. By adding black to the color, the value is made darker, resulting in what is referred to as a “shade.” When white is added to a color, the result is a lighter value, which is referred to as a “tint.”
Tints are lighter versions of the color that are made by mixing a color with white, whereas shades are darker versions of the color that are made by mixing a color with black. For example, pink is a tint of red, while maroon is a shade of red.
These are terms to describe how a color varies from its original hue. If white is added, the lighter version of the color is called a tint of the color. On the other hand, if black is added the, darker version of the color is called a shade of the color.
For shades, multiply each component by 1/4, 1/2, 3/4, etc., of its previous value. The smaller the factor, the darker the shade. For tints, calculate (255 - previous value), multiply that by 1/4, 1/2, 3/4, etc. (the greater the factor, the lighter the tint), and add that to the previous value (assuming each.
In XNA there is the Color.Lerp
static method that does this as the difference between two colours.
Lerp
is a mathematical operation between two floats that changes the value of the first by a ratio of the difference between them.
Here's an extension method to do it to a float
:
public static float Lerp( this float start, float end, float amount) { float difference = end - start; float adjusted = difference * amount; return start + adjusted; }
So then a simple lerp operation between two colours using RGB would be:
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); }
An example of applying this would be something like:
// 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 );
Simply multiply the RGB values by the amount you want to modify the level by. If one of the colors is already at the max value, then you can't make it any brighter (using HSV math anyway.)
This gives the exact same result with a lot less math as switching to HSV and then modifying V. This gives the same result as switching to HSL and then modifying L, as long as you don't want to start losing saturation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With