Sign in to follow this  

[.net] reflection: getting RGB values of all colors in system.drawing

This topic is 4774 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

hello there, im trying to access System.Drawing.Color using reflection to get every RGB value of the colors within it, so i can use those values in other projects without having to copy them by hand. what i wanted to do was creating a c++ header with something like:
namespace Colors
{
    enum Colors_
    {
        Red = RGB( 255, 0, 0 ),
        Blue = RGB( 0, 0, 255 ),
        ...
    };
}

now within that enum i would like to have every color that is on the Color enum in System.Drawing on the .NET framework. each colar has default members with the rgb values of that color. ive tried using C# something like:
public static void Main()
{
    StreamWriter out = new StreamWriter( "Colors.h" );
    MemberInfo [] members = typeof(System.Drawing.Color).GetMembers();

    foreach( MemberInfo in members )
    {
        out.WriteLine( m.Name + " = RGB( " //and now i dont know how to get the R G and B value of the color being read

you see, im trying to generate a C++ header file from C# with an enum with all colors availlable in .NET. i can get the Name of the color, but i cant get the R and G and B value of each one. i know each Color has Color.R Color.G and Color.B properties, but how to get them? hope you understand what im trying to do please share any ideias you might have thanks in advance :D

Share this post


Link to post
Share on other sites
To get the value of a property via reflection use the GetValue method of PropertyInfo.
This means instead of using Type.GetMembers() you probably want to use Type.GetProperties(). Because the properties of interest are static use the form that takes binding flags and pass BindingFlags.Static to avoid getting the A,R,G and B instance properties.
You also may want check the PropertyType to make sure that it is a Color and not something else.
Because the named color properties in Color are static properties you will probasbly have to use the more complicated form of GetValue passing in BindingFlags.Static and (not totaly sure about this) null or the type object as the first obj arg as you don't have an object instance for static calls. You should be safe passing null as the last three args.

Share this post


Link to post
Share on other sites
thanks a lot for the replys :D

so, ive followed your tips and ive come to something like this:


public static int Main( string [] args )
{
StreamWriter file = new StreamWriter( "Colors.h" );
PropertyInfo [] properties = typeof(Color).GetProperties();

foreach( PropertyInfo pi in properties )
{
int R = 0;
int G = 0;
int B = 0;

if( "R" == pi.Name )
R = (int)pi.GetValue( typeof(Color), BindingFlags.Static | BindingFlags.Public, null, null, null );
if( "G" == pi.Name )
G = (int)pi.GetValue( typeof(Color), BindingFlags.Static | BindingFlags.Public, null, null, null );
if( "B" == pi.Name )
B = (int)pi.GetValue( typeof(Color), BindingFlags.Static | BindingFlags.Public, null, null, null );

file.WriteLine( pi.Name + " = RGB( {0}, {1}, {2} ),", R, G, B );
file.Flush();
}
file.Close();
return 0;
}



first of all, in the end the file shows the R G and B properties == 0
example: AliceBlue = RGB( 0, 0, 0 ),
it is well formated, but it doesnt seem to be getting any value.
second of all, i get a "not same type" exception int the GetValue() method when choosing typeof(Color) for the first arg, but it is a Color type isnt it?

thanks for your help :D

Share this post


Link to post
Share on other sites
sorry for replying again, i guess the type of the property must be an int right? after all, the R G and B are. so ive changed to:


if( "R" == pi.Name && typeof(int) == pi.GetType() )
R = (int)pi.GetValue( typeof(int), BindingFlags.Static | BindingFlags.Public, null, null, null );
if( "G" == pi.Name && typeof(int) == pi.GetType() )
G = (int)pi.GetValue( typeof(int), BindingFlags.Static | BindingFlags.Public, null, null, null );
if( "B" == pi.Name && typeof(int) == pi.GetType() )
B = (int)pi.GetValue( typeof(int), BindingFlags.Static | BindingFlags.Public, null, null, null );



no more exceptions, but R G and B are still returnin 0, why is that? maybe something in the GetValue() methos that its not right?

thanks :D

Share this post


Link to post
Share on other sites
Ok, unless I totaly misundersood what you were trying to do in your first example your followup is a bit off.

If you want to print out all of the named colors available in the System.Drawing.Color namesapce (something like Red = 255,0,0; Blue = 0,0,255 etc...) than you are looking at the wrong stuff. The R,G,B,A properties of are not the ones that you are interested in reflecting on. You are interested in reflecting on the huge number of static named color properties that are themselves color values.

If you have an object that may have some properties (R,G,B and A) but you don't really know anything else about it than you might want to do something like what you have started. I don't think that that is the case here.

Try something more like this:


PropertyInfo [] properties = typeof(Color).GetProperties(BindingFlags.Static | BindingFlags.Public);
foreach( PropertyInfo pi in properties ) {
if(pi.PropertyType.Equals(typeof(Color)){
Color c = (Color)pi.GetValue(null,BindingFlags.Static | BindingFlags.Public,null,null,null);
Console.WriteLine(pi.Name+" = "+c.R+","+c.G+","+c.B);

}
}

Share this post


Link to post
Share on other sites
Do you really need to use reflection to get the RGB values of the known colors in System.Drawing?

This is in VB and from a web app but it should show you an easy way to get at the system defined colors RGB values. Easier than doing all the reflection stuff.


Private Sub PrintColors()
Dim myColors() As String = [Enum].GetNames(GetType(System.Drawing.KnownColor))

For Each s As String In myColors
Response.Write(s & "<br>")

Dim c As Color = System.Drawing.Color.FromName(s)

Response.Write(c.R & ":" & c.G & ":" & c.B & "<br>")
Next
End Sub

Share this post


Link to post
Share on other sites
For better or for worse the class lib is designed with Color as a struct and with static properties for the named colors. As it is not an Enum I don't think you can call Enum.GetNames(typeof(Color)) and expect to get anything but an exception.

That said you can probably use the Color.FromName() that natural suggested one the reflected name instead of PropertyInfo.GetValue().

Share this post


Link to post
Share on other sites
Quote:
Original post by turnpast
For better or for worse the class lib is designed with Color as a struct and with static properties for the named colors.

Enumerable types are integral, and Color is not an integral type; that's why it's a struct.

In .NET, however, there is a colors enumeration, and it's already done for you: the KnownColor enumeration. You can do what you'd like with the code below:


System.Array colorsArray = Enum.GetValues(typeof(KnownColor));
KnownColor[] allKnownColors = new KnownColor[colorsArray.Length];
Array.Copy(colorsArray, allKnownColors, colorsArray.Length);

foreach (KnownColor c in allKnownColors)
{
Color col = Color.FromKnownColor(c);
Console.WriteLine("Name: {0}, RGB {1}:{2}:{3}", col.ToString(), col.R, col.G, col.B);
}


Share this post


Link to post
Share on other sites

This topic is 4774 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this