序列化一个 System.Windows.Media.ImageSource 对象。

5

我正在创建一个非常基础的聊天应用程序。我使用tcp连接建立聊天。我经常通过网络流发送序列化的对象,因为这样更容易编程。无论如何,如果我有一个 class person{ public string name{get;set;} },那么序列化该类将非常简单。当我包含一个 public ImageSource Img {get;set;}时,我就无法再序列化那个person类了。

我的序列化方法如下:

Person p = new Person();
p.name = \\some name
p.Img = \\ some image

System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(p.GetType());

x.Serialize(connection.stream, p);//here is when the problem comes. I am not able to serialize it if I include an Img

图像到 XML 序列化有点奇怪。 - Tomas Voracek
我不介意使用不同类型的序列化... - Tono Nam
3个回答

9

你无法将图像序列化为XML,但是可以将其保存到MemoryStream中,并将二进制数据编码为base64。

string ImageToBase64(BitmapSource bitmap)
{
    var encoder = new PngBitmapEncoder();
    var frame = BitmapFrame.Create(bitmap);
    encoder.Frames.Add(frame);
    using(var stream = new MemoryStream())
    {
        encoder.Save(stream);
        return Convert.ToBase64String(stream.ToArray());
    }
}

BitmapSource Base64ToImage(string base64)
{
    byte[] bytes = Convert.FromBase64String(base64);
    using(var stream = new MemoryStream(bytes))
    {
        return BitmapFrame.Create(stream);
    }
}

请注意,就空间而言,base64不是很有效率...如果可能的话,最好以二进制形式传输图像,而不是XML形式。


一旦我将图像作为字符串获取,如何将其转换回图像? - Tono Nam
3
“Base64ToImage”方法似乎存在问题-在“BitmapFrame”实际访问之前,流会被处理掉。我已经在这个答案中描述了修复方法。 - Damir Arh
为了反序列化,我最终使用了BitmapImage而不是BitmapFrame(https://dev59.com/53I-5IYBdhLWcg3wxbfv#1685504)。前者在后续调用中返回第一张图像(因此,在我的UI中始终是同一张图像)。我相信这是我的用户错误。 - Vimes

1

你的方法是正确的,但是一旦类Person包含任何非可序列化对象(例如在你的情况下是ImageSource),它就不再起作用了。

如果我必须在接近你的解决方案的情况下解决它,我会存储图像的byte[],并在反序列化后解析它以重构ImageSource。


1

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