10

System.Drawing.Color has a ToArgb() method to return the Int representation of the color.
In Silverlight, I think we have to use System.Windows.Media.Color. It has A, R, G, B members, but no method to return a single value.
How can I implement ToArgb()? In System.Drawing.Color, ToArgb() consists of

return (int) this.Value;  

System.Windows.Media.Color has a FromArgb(byte A, byte R, byte G, byte B) method. How do I decompose the Int returned by ToArgb() to use with FromArgb()?

Thanks for any pointers...

Donut
  • 110,061
  • 20
  • 134
  • 146
Number8
  • 12,322
  • 10
  • 44
  • 69

3 Answers3

36

Short and fast. Without an extra method call, but with fast operations.

// To integer
int iCol = (color.A << 24) | (color.R << 16) | (color.G << 8) | color.B;

// From integer
Color color = Color.FromArgb((byte)(iCol >> 24), 
                             (byte)(iCol >> 16), 
                             (byte)(iCol >> 8), 
                             (byte)(iCol));
Rene Schulte
  • 2,962
  • 1
  • 19
  • 26
5

Sounds like you're asking two questions here, let me take another stab at it. Regardless, you'll want to look into using the BitConverter class.

From this page:

The byte-ordering of the 32-bit ARGB value is AARRGGBB.

So, to implement ToArgb(), you could write an extension method that does something like this:

public static int ToArgb(this System.Windows.Media.Color color)
{
   byte[] bytes = new byte[] { color.A, color.R, color.G, color.B };
   return BitConverter.ToInt32(bytes, 0);
}

And to "decompose the Int returned by ToArgb() to use with FromArgb()", you could do this:

byte[] bytes = BitConverter.GetBytes(myColor.ToArgb());
byte aVal = bytes[0];
byte rVal = bytes[1];
byte gVal = bytes[2];
byte bVal = bytes[3];  

Color myNewColor = Color.FromArgb(aVal, rVal, gVal, bVal);

Hope this helps.

eAi
  • 572
  • 5
  • 16
Donut
  • 110,061
  • 20
  • 134
  • 146
  • I think you got the arrays backwards. `The byte-ordering of the 32-bit ARGB value is AARRGGBB.` refers to the digits of an 8-hex-digit uint. In little endian (probably the more common case) your code is wrong, blue comes first. – Zarat May 14 '13 at 17:18
  • @Zarat, you are correct for Intel compatible chips. BitConverter doesn't change endian-ness of your byte order, so the same code can have the bytes ordered differently depending on endian-order. – Berin Loritsch Feb 09 '16 at 21:43
0

Just a short note:

Retrieving the integer representation of a "Color" object seems to be 4 times faster for me when calling color.ToArgb() directly instead of using the bitshift-operations in the marked answer. So if you have access to .ToArgb(), always use that!

The thread creator stated he hasn't access to it, so of course the marked answer is still correct, juse don't get confused by the claimed "fast operations" in it.

Just keep in mind: The color of the Color instance is internally already saved as int value, so ToArgb() is just returning it, while accessing each single byte of it to (by properties .A, .R., .G., .B) and then re-ensemble them by bitshifting is kinda moving in a circle.

  • 3
    System.Windows.Media.Color neither has a ToArgb method nor does it store the color internally as an int. Seems you didn't read the question. – Zarat May 14 '13 at 17:16