Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serialize and Store an Image in an XML File

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.

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?

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?

like image 550
user2453973 Avatar asked Sep 17 '13 05:09

user2453973


People also ask

Can you store an image in XML?

Any data can be stored in and retrieved from an XML file as long as you can convert the data to text before writing to the XML file and then convert the text from the XML file into the correct data type when reading it back. 1. Convert the image to an array of bytes.

How do you serialize an image?

You can't serialize an Image . It is typically "hooked into" the sender's graphics environment in ways that serialization is not able to deal with. What you need to do is to mark the img field as transient . The net effect will be that the receiver sees null as the value.

What is serialization in XML?

XML serialization is the process of converting XML data from its representation in the XQuery and XPath data model, which is the hierarchical format it has in a Db2® database, to the serialized string format that it has in an application.

Is XML a serialization format?

XML serialization serializes only the public fields and property values of an object into an XML stream. XML serialization does not include type information. For example, if you have a Book object that exists in the Library namespace, there is no guarantee that it is deserialized into an object of the same type.

How to serialize binary image data using XML serializer?

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 ImageBuffer property to your Person class, which contains the binary image data.

How to store image into XML file?

To store image into XML file: 1 Read all the bytes into memory using File.ReadAllBytes (). 2 Convert the bytes to a Base64 string using Convert.ToBase64String () 3 Write the Base64 Encoded string to your element content.

What is serialization in the framework?

Serialization is the process of taking the state of an object and persisting it in some fashion. The .NET Framework includes powerful objects that can serialize any object to XML. The System.Xml.Serialization namespace provides this capability.

How to convert XML to a C #object?

To convert this XML into an object, first you need to create a similar class structure in C#. Your XML and C# objects are ready. Let's see the final step of converting XML into a C# object. To do that, you need to use System.Xml.Serialization.XmlSerializer to serialize it.


2 Answers

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[] ImageBuffer property to your Person class, which contains the binary image data. You would then also set the XmlIgnore attribute on the Image property to suppress its (de)serialization, and set XmlElement("Image") on the ImageBuffer properties to (de)serialize it as <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.

like image 128
Clemens Avatar answered Sep 30 '22 09:09

Clemens


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?

like image 30
Robert Levy Avatar answered Sep 30 '22 10:09

Robert Levy