drupal hit counter
Jerry Huang | Windows Phone Development

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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
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 SILVERLIGHTprivate string ImageToString(BitmapSource image)
#elseprivate string ImageToString(Bitmap image)
#endif{byte[] byteArray;using (MemoryStream stream = new MemoryStream()){#if SILVERLIGHTWriteableBitmap bmp = new WriteableBitmap((BitmapSource)image);bmp.SaveJpeg(stream, bmp.PixelWidth, bmp.PixelHeight, 0, 100);byteArray = stream.ToArray();
#elseimage.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);stream.Flush();byteArray = stream.ToArray();
#endif}return Convert.ToBase64String(byteArray);}public SerializableImage() { }#if SILVERLIGHTpublic SerializableImage(Uri uri){using (Stream stream = Application.GetResourceStream(uri).Stream){this.SetSource(stream);}}#elsepublic SerializableImage(Image image){this.Source = (Bitmap)image;}protected override Freezable CreateInstanceCore() { return new SerializableImage(); }public Bitmap Source { get;  set; }
#endifprivate void StringToImage(string imageString){if (imageString == null)throw new ArgumentNullException("imageString");byte[] array = Convert.FromBase64String(imageString);#if SILVERLIGHTthis.SetSource (new MemoryStream(array));
#elseSource = (Bitmap)Image.FromStream(new MemoryStream(array));
#endif}#region IXmlSerializable Memberspublic 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 SILVERLIGHTstring img = ImageToString( this);
#elsestring img = ImageToString(this.Source);
#endifimgSerializer.Serialize(writer, img);writer.WriteEndElement();}#endregion}
}