wpf 在 XML 文件中序列化和存储图像

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18841690/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 09:39:49  来源:igfitidea点击:

Serialize and Store an Image in an XML File

c#wpfimageserializationobservablecollection

提问by user2453973

Got a little bit of a problem. I have a program that builds an observable collection of Users. The User has a Firstname, Lastname, and Image. I can add the user to the observable collection, but I also want to save the collection and load it everytime I reopen the program.

有点问题。我有一个程序可以构建一个可观察的用户集合。用户有名字、姓氏和图像。我可以将用户添加到 observable 集合,但我也想保存集合并在每次重新打开程序时加载它。

My problem is that while its fairly easy to save a firstname and lastname, the writer can't write the image to the xml file. Is there any way around this?

我的问题是,虽然保存名字和姓氏相当容易,但作者无法将图像写入 xml 文件。有没有办法解决?

Here's what I have so far:

这是我到目前为止所拥有的:

the observable collection:

可观察集合:

ObservableCollection<VendorClass> ProfileList = new ObservableCollection<VendorClass>();

the problematic writer:

有问题的作家:

XmlSerializer xs = new XmlSerializer(typeof(ObservableCollection<VendorClass>));
        using (StreamWriter wr = new StreamWriter("vendors.xml")) //Data/customers.xml
        {
            xs.Serialize(wr, ProfileList);
        }

Any ideas? And if there does exist a solution to write in an image, is there a viable way to read it out again?

有任何想法吗?如果确实存在写入图像的解决方案,是否有可行的方法再次读取它?

回答by Clemens

XmlSerializer can't serialize or deserialize the WPF image types like BitmapImage etc. It is however able to (de)serialize byte arrays. So you may add a byte[] ImageBufferproperty to your Person class, which contains the binary image data. You would then also set the XmlIgnoreattribute on the Imageproperty to suppress its (de)serialization, and set XmlElement("Image")on the ImageBufferproperties to (de)serialize it as <Image>...</Image>.

XmlSerializer 不能序列化或反序列化 WPF 图像类型,如 BitmapImage 等。但是它能够(反)序列化字节数组。因此,您可以byte[] ImageBuffer向 Person 类添加一个属性,其中包含二进制图像数据。这样,你会也设置XmlIgnore属性的Image属性来抑制它的(反)序列化,并设置XmlElement("Image")ImageBuffer性能(反)序列化它<Image>...</Image>

public class User
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    [XmlIgnore]
    public BitmapSource Image { get; set; }

    [XmlElement("Image")]
    public byte[] ImageBuffer
    {
        get
        {
            byte[] imageBuffer = null;

            if (Image != null)
            {
                using (var stream = new MemoryStream())
                {
                    var encoder = new PngBitmapEncoder(); // or some other encoder
                    encoder.Frames.Add(BitmapFrame.Create(Image));
                    encoder.Save(stream);
                    imageBuffer = stream.ToArray();
                }
            }

            return imageBuffer;
        }
        set
        {
            if (value == null)
            {
                Image = null;
            }
            else
            {
                using (var stream = new MemoryStream(value))
                {
                    var decoder = BitmapDecoder.Create(stream,
                        BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
                    Image = decoder.Frames[0];
                }
            }
        }
    }
}

This approach has also been suggested for properties of type Bitmap in this answer.

此答案中,还建议将此方法用于 Bitmap 类型的属性。

回答by Robert Levy

You would base64 encode the image to convert it to a string and then write that into a CDATA section. See How do you serialize a string as CDATA using XmlSerializer?

您可以对图像进行 base64 编码以将其转换为字符串,然后将其写入 CDATA 部分。请参阅如何使用 XmlSerializer 将字符串序列化为 CDATA?