Skip to content

Commit c75cbfb

Browse files
committed
Added extension methods for System.Windows.Media.Color.
1 parent 99a894d commit c75cbfb

File tree

2 files changed

+253
-0
lines changed

2 files changed

+253
-0
lines changed

ColorSetKit/ColorExtension.cs

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
/*******************************************************************************
2+
* The MIT License (MIT)
3+
*
4+
* Copyright (c) 2018 Jean-David Gadina - www.imazing.com
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
******************************************************************************/
24+
25+
using System;
26+
using System.Collections.Generic;
27+
using System.Linq;
28+
using System.Text;
29+
30+
namespace ColorSetKit
31+
{
32+
public static class ColorExtension
33+
{
34+
private struct HSL
35+
{
36+
public double Hue;
37+
public double Saturation;
38+
public double Lightness;
39+
}
40+
41+
private struct RGB
42+
{
43+
public double Red;
44+
public double Green;
45+
public double Blue;
46+
}
47+
48+
public struct HSLComponents
49+
{
50+
public double Hue;
51+
public double Saturation;
52+
public double Lightness;
53+
public double Alpha;
54+
}
55+
56+
public struct RGBComponents
57+
{
58+
public double Red;
59+
public double Green;
60+
public double Blue;
61+
public double Alpha;
62+
}
63+
64+
public static System.Windows.Media.Color FromHSL( double hue, double saturation, double lightness, double alpha )
65+
{
66+
RGB rgb = HSLToRGB( hue, saturation, lightness );
67+
68+
return new System.Windows.Media.Color
69+
{
70+
R = ( byte )( Math.Floor( rgb.Red * 255 ) ),
71+
G = ( byte )( Math.Floor( rgb.Green * 255 ) ),
72+
B = ( byte )( Math.Floor( rgb.Blue * 255 ) ),
73+
A = ( byte )( Math.Floor( alpha * 255 ) )
74+
};
75+
}
76+
77+
public static System.Windows.Media.Color BestTextColorForBackgroundColor( System.Windows.Media.Color background )
78+
{
79+
return BestTextColorForBackgroundColor( background, System.Windows.Media.Color.FromRgb( 255, 255, 255 ), System.Windows.Media.Color.FromRgb( 0, 0, 0 ) );
80+
}
81+
82+
public static System.Windows.Media.Color BestTextColorForBackgroundColor( System.Windows.Media.Color background, System.Windows.Media.Color lightTextColor, System.Windows.Media.Color darkTextColor )
83+
{
84+
double r = background.R;
85+
double g = background.G;
86+
double b = background.B;
87+
88+
double contrast = ( ( r * 299 ) + ( g * 287 ) + ( b * 114 ) ) / 1000;
89+
90+
return ( contrast > 150 ) ? darkTextColor : lightTextColor;
91+
}
92+
93+
public static RGBComponents GetRGB( this System.Windows.Media.Color self )
94+
{
95+
return new RGBComponents
96+
{
97+
Red = self.R / 255.0,
98+
Green = self.G / 255.0,
99+
Blue = self.B / 255.0,
100+
Alpha = self.A / 100.0
101+
};
102+
}
103+
104+
public static HSLComponents GetHSL( this System.Windows.Media.Color self )
105+
{
106+
HSL hsl = RGBToHSL( self.R / 255.0, self.G / 255.0, self.B / 255.0 );
107+
108+
return new HSLComponents
109+
{
110+
Hue = hsl.Hue,
111+
Saturation = hsl.Saturation,
112+
Lightness = hsl.Lightness,
113+
Alpha = self.A / 100.0,
114+
};
115+
}
116+
117+
public static System.Windows.Media.Color ByChangingHue( this System.Windows.Media.Color self, double h )
118+
{
119+
RGBComponents rgb = self.GetRGB();
120+
HSL hsl = RGBToHSL( rgb.Red, rgb.Green, rgb.Blue );
121+
122+
return FromHSL( h, hsl.Saturation, hsl.Lightness, rgb.Alpha );
123+
}
124+
125+
public static System.Windows.Media.Color ByChangingSaturation( this System.Windows.Media.Color self, double s )
126+
{
127+
RGBComponents rgb = self.GetRGB();
128+
HSL hsl = RGBToHSL( rgb.Red, rgb.Green, rgb.Blue );
129+
130+
return FromHSL( hsl.Hue, s, hsl.Lightness, rgb.Alpha );
131+
}
132+
133+
public static System.Windows.Media.Color ByChangingLightness( this System.Windows.Media.Color self, double l )
134+
{
135+
RGBComponents rgb = self.GetRGB();
136+
HSL hsl = RGBToHSL( rgb.Red, rgb.Green, rgb.Blue );
137+
138+
return FromHSL( hsl.Hue, hsl.Saturation, l, rgb.Alpha );
139+
}
140+
141+
private static RGB HSLToRGB( double h, double s, double l )
142+
{
143+
double t1;
144+
double t2;
145+
double[] rgb = { 0, 0, 0 };
146+
147+
if( s == 0.0 )
148+
{
149+
return new RGB { Red = l, Green = l, Blue = l };
150+
}
151+
152+
if( l < 0.5 )
153+
{
154+
t2 = l * ( 1.0 + s );
155+
}
156+
else
157+
{
158+
t2 = l + s - ( l * s );
159+
}
160+
161+
t1 = ( 2.0 * l ) - t2;
162+
163+
rgb[ 0 ] = h + ( 1.0 / 3.0 );
164+
rgb[ 1 ] = h;
165+
rgb[ 2 ] = h - ( 1.0 / 3.0 );
166+
167+
for( int i = 0; i < 3; i++ )
168+
{
169+
if( rgb[ i ] < 0.0 )
170+
{
171+
rgb[ i ] += 1.0;
172+
}
173+
else if( rgb[ i ] > 1.0 )
174+
{
175+
rgb[ i ] -= 1.0;
176+
}
177+
178+
if( rgb[ i ] * 6.0 < 1.0 )
179+
{
180+
rgb[ i ] = t1 + ( ( t2 - t1 ) * 6.0 * rgb[ i ] );
181+
}
182+
else if( rgb[ i ] * 2.0 < 1.0 )
183+
{
184+
rgb[ i ] = t2;
185+
}
186+
else if( rgb[ i ] * 3.0 < 2.0 )
187+
{
188+
rgb[ i ] = t1 + ( ( t2 - t1 ) * ( ( 2.0 / 3.0 ) - rgb[ i ] ) * 6.0 );
189+
}
190+
else
191+
{
192+
rgb[ i ] = t1;
193+
}
194+
}
195+
196+
return new RGB { Red = rgb[ 0 ], Green = rgb[ 1 ], Blue = rgb[ 2 ] };
197+
}
198+
199+
private static HSL RGBToHSL( double r, double g, double b )
200+
{
201+
double v = Math.Max( Math.Max( r, g ), b );
202+
double m = Math.Min( Math.Min( r, g ), b );
203+
double h = 0;
204+
double s = 0;
205+
double l;
206+
double vm;
207+
double r2;
208+
double g2;
209+
double b2;
210+
211+
l = ( m + v ) / 2.0;
212+
213+
if( l <= 0.0 )
214+
{
215+
return new HSL { Hue = h, Saturation = s, Lightness = l };
216+
}
217+
218+
vm = v - m;
219+
s = vm;
220+
221+
if( s > 0.0 )
222+
{
223+
s /= ( ( l <= 0.5 ) ? v + m : 2.0 - v - m );
224+
}
225+
else
226+
{
227+
return new HSL { Hue = h, Saturation = s, Lightness = l };
228+
}
229+
230+
r2 = ( v - r ) / vm;
231+
g2 = ( v - g ) / vm;
232+
b2 = ( v - b ) / vm;
233+
234+
if( r == v )
235+
{
236+
h = ( g == m ) ? 5.0 + b2 : 1.0 - g2;
237+
}
238+
else if( g == v )
239+
{
240+
h = ( b == m ) ? 1.0 + r2 : 3.0 - b2;
241+
}
242+
else
243+
{
244+
h = ( r == m ) ? 3.0 + g2 : 5.0 - r2;
245+
}
246+
247+
h /= 6.0;
248+
249+
return new HSL { Hue = h, Saturation = s, Lightness = l };
250+
}
251+
}
252+
}

ColorSetKit/ColorSetKit.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
</ItemGroup>
4646
<ItemGroup>
4747
<Compile Include="Color.cs" />
48+
<Compile Include="ColorExtension.cs" />
4849
<Compile Include="ColorPair.cs" />
4950
<Compile Include="ColorSet.cs" />
5051
<Compile Include="ColorSetStream.cs" />

0 commit comments

Comments
 (0)