问题
In my app I allow the user to build a color, and then show him the name or value of the color later on. If the user picks red (full red, not red-ish), I want to show him "red". If he picks some strange color, then the hex value would be just fine. Here's sample code that demonstrates the problem:
static string GetName(int r, int g, int b)
{
Color c = Color.FromArgb(r, g, b); // Note that specifying a = 255 doesn't make a difference
if (c.IsNamedColor)
{
return c.Name;
}
else
{
// return hex value
}
}
Even with very obvious colors like red IsNamedColor
never returns true. Looking at the ARGB values for my color and Color.Red
, I see no difference. However, calling Color.Red.GetHashCode()
returns a different hash code than Color.FromArgb(255, 0, 0).GetHashCode()
.
How can I create a color using user specified RGB values and have the Name
property come out right?
回答1:
From MSDN.
Property Value Type: System.Boolean
true if this Color was created by using either the FromName method or the FromKnownColor method; otherwise, false.
You could build a map from all KnownColor
s rgb tuples to names I suppose.
回答2:
This probably isn't the fastest method, but it does work. Colors don't have to match exactly for the name to be chosen e.g. GetColorName(Color.FromArgb(254, 254, 0));
will still return Yellow.
I've deliberately left out access modifiers
Color[] KnownColors;
void Init (){
KnownColors = (from colorInfo in typeof(Color).GetProperties(BindingFlags.Static | BindingFlags.CreateInstance |BindingFlags.Public)
where colorInfo.PropertyType == typeof (Color)
select (Color)colorInfo.GetValue(null, null)).Where (c => c.A != 0).ToArray();
}
string GetColorName(Color inColour)
{
// I'm just getting started on LINQ so im not
// sure how to do this with it (Maybe some one can help out with that)
int MinDistance = int.MaxValue;
Color closestKnown = Color.Black;
foreach (var c in KnownColors)
{
var d = ColorDistance(c, inColour);
if (d < MinDistance){
closestKnown = c;
MinDistance = d;
}
}
return closestKnown.Name;
}
int ColorDistance(Color c1, Color c2)
{
var ad = (c1.A - c2.A);
var rd = (c1.R - c2.R);
var gd = (c1.G - c2.G);
var bd = (c1.B - c2.B);
return (ad * ad) + (rd * rd) + (gd * gd) + (bd * bd);
}
来源:https://stackoverflow.com/questions/2032398/why-does-color-isnamedcolor-not-work-when-i-create-a-color-using-color-fromargb