Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I serialize a System.Windows.Media.Color object to an sRGB string?

I need to serialize a color used in a WPF application to a database. I'd like to use the sRGB values, because they're more familiar to those of us that have spent the last few years doing web development.

How can a get an ARGB string (like #FFFFFFFF) from a System.Windows.Media.Color object?

UPDATE: I was misled by the documentation on MSDN. As @Kris noted below, the documentation for the ToString() method is incorrect. Although it says that ToString() "creates a string representation of the color using the ScRGB channels", it will actually return a string in ARGB hex format if the color was created using the FromARGB() method. It's an undocumented feature, I suppose.

See http://msdn.microsoft.com/en-us/library/ms606572.aspx

like image 311
dthrasher Avatar asked Jul 23 '10 02:07

dthrasher


4 Answers

If you create your colors using either Color.FromRgb or Color.FromArgb instead of FromScRgb you should get a hex string result from ToString.

If you want to do it manually

string.Format("#{0:X2}{1:X2}{2:X2}{3:X2}", c.A, c.R, c.G, c.B);

You can use int.Parse(,NumberStyles.HexNumber) to go the other way.

Note sRGB and scRGB refer to different color spaces, make sure your using the one you want.

like image 100
Kris Avatar answered Nov 18 '22 14:11

Kris


You can also do it this way:

string myHex = new ColorConverter().ConvertToString(myColor);
like image 41
Anthony Bobenrieth Avatar answered Nov 18 '22 14:11

Anthony Bobenrieth


I created a struct to handle conversion and serialisation. It solves two problems for me: it is serialisable and it corrects the spelling ;)

[Serializable]
public struct Colour
    {
    public byte A;
    public byte R;
    public byte G;
    public byte B;

    public Colour(byte a, byte r, byte g, byte b)
        {
        A = a;
        R = r;
        G = g;
        B = b;
        }

    public Colour(Color color)
        : this(color.A, color.R, color.G, color.B)
        {
        }

    public static implicit operator Colour(Color color)
        {
        return new Colour(color);
        }

    public static implicit operator Color(Colour colour)
        {
        return Color.FromArgb(colour.A, colour.R, colour.G, colour.B);
        }
    }

Just use Colour where you would otherwise use System.Windows.Media.Color

like image 5
Phil J Pearson Avatar answered Nov 18 '22 14:11

Phil J Pearson


If your purpose is to serialize to a file and deserialize back to the color object, I think you are better of to convert color to an Int32 and vice versa. It is no brainier to serialize/deserialize Int32. If this is your purpose, here is the code: Color To Int32:

        byte[] color = new byte[4];
        color[0] = Color.B;
        color[1] = Color.G;
        color[2] = Color.R;
        color[3] = Color.A;
        Int32 intColor = System.BitConverter.ToInt32(color, 0);

Int32 To Color:

byte[] bytes = System.BitConverter.GetBytes(intColor);
Color =new System.Windows.Media.Color(){B= bytes[0], G=bytes[1], R=bytes[2], A=bytes[3]};
like image 2
Wayne Lo Avatar answered Nov 18 '22 16:11

Wayne Lo