drupal hit counter
Jerry Huang | Serializing image in WP7

Jerry Huang apps and developing apps

Serializing image in WP7

15. April 2011 03:23 by Jerry in Windows Phone Development

This post is to celebrate my 2nd app - Smart Dial has been approved in marketplace.

None of the build in imaging classes in Windows Phone or Silverlight is serializable, that's why I have to build my own class.Cool

To serialize a custom object, the class need to implement IXmlSerializable interface. So my class inherits BitmapSource and then implement IXmlSerializable.

The idea of the whole thing is actually pretty simple. Just covert the image into byte array, and then transform to Base64 string, and backward for deserialization. With such approach, we are able to ship the image within XML(i.e. pure text). This is how my app (Smart Dial) to transfer contact photos between WP7 and server.

 Since my Smart Dial solution consists 2 client programs in handset device and desktop computer, I made the class compatible with both silverlight (WP7) and Winform (base on .Net 3.5). However, somehow I can't load the image source to itself in winform version. The BitmapSource in winform doesn't contain the SetSource method, I have use a stupid property (Source).

Simply copy and paste and compile and enjoyLaughing

[code language=C#]   

using System;
using System.Windows;
using System.Xml.Serialization;
using System.IO;
using System.Windows.Media.Imaging;
using System.Xml.Schema;
using System.Xml;
 #if !SILVERLIGHT
using System.Drawing;
#endif
namespace SmartDial.Data
{

    public class SerializableImage : BitmapSource, IXmlSerializable
    {
 #if SILVERLIGHT
        private string ImageToString(BitmapSource image)
#else
        private string ImageToString(Bitmap image)
#endif
        {
           
            byte[] byteArray;

            using (MemoryStream stream = new MemoryStream())
            {
 #if SILVERLIGHT
                WriteableBitmap bmp = new WriteableBitmap((BitmapSource)image);
                bmp.SaveJpeg(stream, bmp.PixelWidth, bmp.PixelHeight, 0, 100);
                byteArray = stream.ToArray();
#else
                image.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
                stream.Flush();
                byteArray = stream.ToArray();
#endif
              
            }

            return Convert.ToBase64String(byteArray);
        }
        public SerializableImage() { }
 #if SILVERLIGHT
       
        public SerializableImage(Uri uri)
        {

            using (Stream stream = Application.GetResourceStream(uri).Stream)
            {
                this.SetSource(stream);
            }
        }

#else
        public SerializableImage(Image image)
        {
            this.Source = (Bitmap)image;
        }
        protected override Freezable CreateInstanceCore() { return new SerializableImage(); }
        public Bitmap Source { get;  set; }
#endif

        private void StringToImage(string imageString)
        {
            if (imageString == null)
                throw new ArgumentNullException("imageString");

            byte[] array = Convert.FromBase64String(imageString);
 #if SILVERLIGHT
            this.SetSource (new MemoryStream(array));
#else
            Source = (Bitmap)Image.FromStream(new MemoryStream(array));
#endif
          

        }


        #region IXmlSerializable Members

        public XmlSchema GetSchema()
        {
            throw new NotImplementedException();
        }

        public void ReadXml(XmlReader reader)
        {


            if (reader.IsEmptyElement || !reader.Read())
            {
                return;
            }
            XmlSerializer imgSerializer = new XmlSerializer(typeof(string));
            while (reader.NodeType != XmlNodeType.EndElement)
            {
                reader.ReadStartElement("SerializedImage");

                string img = (string)imgSerializer.Deserialize(reader);
                reader.ReadEndElement();

                reader.MoveToContent();

                StringToImage(img);
            }
            reader.ReadEndElement();
        }

        public void WriteXml(XmlWriter writer)
        {
            XmlSerializer imgSerializer = new XmlSerializer(typeof(string));

            writer.WriteStartElement("SerializedImage");
 #if SILVERLIGHT
            string img = ImageToString( this);
#else
            string img = ImageToString(this.Source);
#endif
            imgSerializer.Serialize(writer, img);
            writer.WriteEndElement();

        }

        #endregion
    }
}

[/code]

Comments (1) -

Kevin Oliver 12/12/2011 10:51:34 AM United States #
Kevin Oliver

You Rock!!! I was have a terrible time figuring out how to save images in WP7. Your code saved me. Thanks.