Jonathan Birkholz

Lighten Color in C#

The following piece of code was originally written by Marcus Egger in a converter. I did a bit of refactoring to clean up the code and moved the code outside a converter and into an extension method.

The extension method is off of Color and returns another Color. Now since it is an extension method you can use it in a converter or a markup extension (the latter being my favorite use).

You can also get this code from my color project on GitHub :

http://github.com/RookieOne/Colors

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
public static class LightenColorExtension
{
/// <summary>
/// This method applies lighting to a color.
/// For instance, a color that has a lighting factor of 1 applies, appears at its original value.
/// A color with a lighting factor of 0.5 appears only half as bright as it was before.
/// A color with a lighting factor of 1.5 appears roughly twice as bright as before.
/// A color with a lightning factor of 2 appears white.
/// </summary>
/// <param name="originalColor">Base color</param>
/// <param name="lightFactor">
/// Amount of light applied to the color
/// </param>
/// <returns>Lit color</returns>
/// <remarks>
/// This routine is very fast. Even when using it in tight loops, I (Markus) have not been able to
/// meassure a significant amount of time spent in this routine (always less than 1ms). I was originally
/// concerened about the performance of this, so I added a caching mechanism, but that slowed things down
/// by 2 orders of magnitude.
/// </remarks>
public static Color Lighten(this Color originalColor, float lightFactor)
{
if (TransformationNotNeeded(lightFactor))
return originalColor;
if (RealBright(lightFactor))
return System.Windows.Media.Colors.White;
if (ShouldDarken(lightFactor))
return DarkenColor(originalColor, lightFactor);
return LightenColor(originalColor, lightFactor);
}
private static bool TransformationNotNeeded(float lightFactor)
{
var value = lightFactor - 1.0f;
return value < 0.01f
&& value > -0.01f;
}
private static bool RealBright(float lightFactor)
{
return lightFactor >= 2.0f;
}
private static bool ShouldDarken(float lightFactor)
{
return lightFactor < 1.0f;
}
private static Color DarkenColor(Color color, float lightFactor)
{
var red = (byte) (color.R*lightFactor);
var green = (byte) (color.G*lightFactor);
var blue = (byte) (color.B*lightFactor);
return Color.FromRgb(red, green, blue);
}
private static Color LightenColor(Color color, float lightFactor)
{
// Lighten
// We do this by approaching 256 for a light factor of 2.0f
float fFactor2 = lightFactor;
if (fFactor2 > 1.0f)
{
fFactor2 -= 1.0f;
}
var red = LightenColorComponent(color.R, fFactor2);
var green = LightenColorComponent(color.G, fFactor2);
var blue = LightenColorComponent(color.B, fFactor2);
return Color.FromRgb(red, green, blue);
}
private static byte LightenColorComponent(byte colorComponent, float fFactor)
{
var inverse = 255 - colorComponent;
colorComponent += (byte) (inverse*fFactor);
return colorComponent < 255
? colorComponent
: (byte) 255;
}
}

C#, WPF