如何将System.Windows.Media.Color对象序列化为sRGB字符串?

18

我需要将WPF应用程序中使用的颜色序列化到数据库中。我想使用sRGB值,因为对于那些过去几年从事Web开发的人来说,这更加熟悉。

如何从System.Windows.Media.Color对象获取ARGB字符串(例如#FFFFFFFF)?

更新:我被MSDN上的文档误导了。正如@Kris在下面指出的那样,ToString()方法的文档是不正确的。虽然它说ToString()“使用ScRGB通道创建颜色的字符串表示形式”,但如果使用FromARGB()方法创建颜色,则实际上会返回一个ARGB十六进制格式的字符串。我想这是一个未记录的特性。

请参见http://msdn.microsoft.com/en-us/library/ms606572.aspx

7个回答

24

如果你使用Color.FromRgb或Color.FromArgb创建颜色,而不是使用FromScRgb,那么你应该可以通过ToString方法得到一个十六进制字符串结果。

如果你想手动处理它

string.Format("#{0:X2}{1:X2}{2:X2}{3:X2}", c.A, c.R, c.G, c.B);
你可以使用int.Parse(,NumberStyles.HexNumber)来实现相反的转换。
请注意,sRGB和scRGB是不同的颜色空间,请确保使用您想要的那个。

你的意思是如果我使用FromArgb创建Color对象,ToString会返回ARGB十六进制字符串而不是ScRgb值?这与MSDN文档中所说的相矛盾:http://msdn.microsoft.com/en-us/library/ms606572.aspx。 - dthrasher
我在文档中没有注意到这一点,但是在使用这些方法时确实会生成十六进制格式。在反射器中查看,设置了一个标志,该标志在ToString实现中使用。 - Kris
是的。ToString() 给了我想要的格式。看起来 MSDN 文档不完整。 - dthrasher
如果按照提到的方式创建,ToString函数可以正常工作。 https://referencesource.microsoft.com/#PresentationCore/Core/CSharp/System/Windows/Media/Color.cs,7df649cf464cd38e,references - user487779

10

你也可以这样做:

string myHex = new ColorConverter().ConvertToString(myColor);

ColorConverter 中没有这样的方法。 - wingerse
1
@EmpereurAiman 这是继承的 https://msdn.microsoft.com/zh-cn/library/92ybstc2(v=vs.110).aspx - RJFalconer
1
你不能只是使用.ToString()吗? - Epirocks
这会在内部调用Color.ToString()。 - Daniel Rose

5

我创建了一个结构体来处理转换和序列化。它为我解决了两个问题:它是可序列化的,而且它还纠正了拼写错误;)

[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);
        }
    }

只需在原本使用 System.Windows.Media.Color 的地方改用 Colour 即可。


兄弟,Color 是美式拼写。Colour 是英式拼写。 - wingerse
10
这叫讽刺。 - Ricky

2
如果您的目的是将颜色对象序列化到文件并反序列化回来,我认为最好将颜色转换为Int32,反之亦然。将Int32进行序列化/反序列化非常简单。如果这是您的目的,以下是代码: 颜色转换为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转颜色:

byte[] bytes = System.BitConverter.GetBytes(intColor);
Color =new System.Windows.Media.Color(){B= bytes[0], G=bytes[1], R=bytes[2], A=bytes[3]};

1

System.Windows.Media.Color类内置实现了toString()方法,可以返回该颜色的十六进制代码。

以下是该类接口的代码片段:

        //
        // Summary:
        //     Creates a string representation of the color using the sRGB channels.
        //
        // Returns:
        //     The string representation of the color. The default implementation represents
        //     the System.Byte values in hex form, prefixes with the # character, and starts
        //     with the alpha channel. For example, the System.Windows.Media.Color.ToString()
        //     value for System.Windows.Media.Colors.AliceBlue is #FFF0F8FF.
        public override string ToString();

1

这个答案是关于GDI颜色的,而不是WPF,所以可能帮助不大。

你可以像这样获取HTML颜色字符串(并返回)

System.Drawing.Color c = System.Drawing.ColorTranslator.FromHtml("#F5F7F8");
String strHtmlColor = System.Drawing.ColorTranslator.ToHtml(c);

这里是MSDN文档。


3
这是针对System.Drawing.Color(GDI+)而非System.Windows.Media.Color(WPF)的。 - AndrewS

0

你可以从Color实例中获取A、R、G和B值作为字节,因此你只需要将字节转换为十六进制并将十六进制值作为字符串连接起来。

byte[]转十六进制字符串


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接