167
167
114d * color2.Blue) / 1000d;
168
168
return Math.Abs(br1 - br2);
171
// algorithm ported from JavaScript to C# from:
172
// http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
173
internal static HslColor ToHSL(TextColor color)
175
var R = color.Red / 255d;
176
var G = color.Green / 255d;
177
var B = color.Blue / 255d;
178
var max = Math.Max(Math.Max(R, G), B);
179
var min = Math.Min(Math.Min(R, G), B);
182
var range = max + min;
185
S = 0d; // achromatic
187
var diff = max - min;
188
S = L > 0.5d ? diff / (2 - diff) : diff / range;
190
H = (G - B) / diff + (G < B ? 6d : 0d);
191
} else if (max == G) {
192
H = (B - R) / diff + 2;
193
} else if (max == B) {
194
H = (R - G) / diff + 4;
198
return new HslColor(H, S, L);
201
public static TextColor GetNearestColor(TextColor color, IEnumerable<TextColor> palette)
203
if (palette == null) {
204
throw new ArgumentNullException("palette");
207
var hslColor1 = ToHSL(color);
208
TextColor nearestColor = null;
209
double nearestDifference = Double.MaxValue;
210
foreach (var color2 in palette) {
211
// compute the Euclidean distance between the two HSL colors
212
// without root square as we only compare the values
213
// see http://en.wikipedia.org/wiki/Color_difference#Delta_E
214
var hslColor2 = ToHSL(color2);
215
var H1 = hslColor1.Hue;
216
var S1 = hslColor1.Saturation;
217
var L1 = hslColor1.Lightness;
218
var H2 = hslColor2.Hue;
219
var S2 = hslColor2.Saturation;
220
var L2 = hslColor2.Lightness;
221
var Hdelta = H1 - H2;
222
var Sdelta = S1 - S2;
223
var Ldelta = L1 - L2;
224
var deltaE = (Hdelta * Hdelta) +
227
if (deltaE < nearestDifference) {
228
nearestDifference = deltaE;
229
nearestColor = color2;
232
// found perfect match, can't get better than that
239
internal class HslColor
241
public double Hue { get; set; }
242
public double Saturation { get; set; }
243
public double Lightness { get; set; }
245
public HslColor(double H, double S, double L)