Enumerate all Known Colors and put them in the dictionary
Dictionary<KnownColor, int> colorsRGB;
can be done this way:
int
numAliceBlue = (int)KnownColor.AliceBlue,
numYellowGreen = (int)KnownColor.YellowGreen,
numColors = numYellowGreen - numAliceBlue + 1;
colorsRGB = new Dictionary<KnownColor, int>(numColors);
for (int i = numAliceBlue; i <= numYellowGreen; i++)
{
KnownColor kc = (KnownColor)i;
colorsRGB.Add(kc, Color.FromKnownColor(kc).ToArgb());
}
Then I can sort the collection using LINQ:
Sort by name:
var sortedColors = (from clr in colorsRGB
orderby clr.Key
select clr).ToArray();
by RGB value:
by RGB value:
var sortedColors = (from clr in colorsRGB
orderby clr.Value descending
select clr).ToArray();
I created a function ColorWeight to “weight” a color (just sum of R, G, and B components),
And even can sort by the “weight”:
var sortedColors = (from clr in colorsRGB
orderby ColorWeight(clr.Key) descending
select clr).ToArray();
I do like LINQ!
For the test I draw buttons with KnownColor as background. I wanted to have foreground color to be recognizable on the background.
This turn out to be not easy task. I did not want to mess with non-RGB presentations (like HSV or HSL) which would simplify the task.
At first I tried “inverted” color:
return Color.FromArgb((int)backColor.ToArgb() ^ 0xF0F0F0);
It did not work well.
So I created “color weight”
private int ColorWeight(Color color)
{
int bColor = (int)color.ToArgb(),
r = (bColor & 0x00FF0000) >> 16,
g = (bColor & 0x0000FF00) >> 8,
b = bColor & 0x000000FF;
return r + g + b;
}
It is not perfect, but kind of fit the purpose: after all I put Black text if “weight” > 0x60+0x60+0x60 and White text otherwise.
This is the result:
No comments:
Post a Comment