Tuesday, March 4, 2008

Image Serialization C#

Serialization is the process of saving an object onto a storage medium (such as a file, or a memory buffer) or to transmit it across a network connection link in binary form. The series of bytes or the format can be used to re-create an object that is identical in its internal state to the original object (actually, a clone).The reverse process of Serialization is called Deserialization.
Refer : wikipedia - serialization

For explaining one feature of Serialization I shall quote an example.

There are some cases in which we don't want to expose our images used in a project but have to use them.Here we can implement serialization.

We keep these images needed in the serialized form and use this after deserializing the same.All the images can be stored as a single serialized file.

To illustrate the same with example code, we shall start with the ImageClass.cs file, which contains

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace serializationProject
{
[Serializable()]
public class ImageClass
{
private Image _imageObject;
private string _imageName;

public ImageClass()
{ }

public Image ImageObject
{
get
{
return _imageObject;
}
set
{
_imageObject = value;
}
}

public string ImageName
{
get
{
return _imageName;
}
set
{
_imageName = value;
}
}

public ImageClass(SerializationInfo info, StreamingContext cntxt)
{
this._imageObject = (Image)info.GetValue("ImageObject", typeof(Image));
this._imageName = (string)info.GetValue("ImageName", typeof(string));
}
}
}

Now we require a serialize object class to store the images generated from the Image Class.

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace serializationProject
{
[Serializable()]
public class ObjectToSerialize : ISerializable
{
private List _images;

public ObjectToSerialize()
{ }

public List Images
{
get
{
return _images;
}
set
{
_images = value;
}
}

public ObjectToSerialize(SerializationInfo info, StreamingContext cntxt)
{
this.Images=(List)info.GetValue("Images",typeof(List));
}

public void GetObjectData(SerializationInfo info, StreamingContext cntxt)
{
info.AddValue("Images", this.Images);
}
}
}

This class returns the images as a List Object.

Now the next task is to write the functions to perform the serialization and the deserialization of the images.

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace serializationProject
{
public class Serializer
{
public void SerializeObject(string filename,
ObjectToSerialize objectToSerialize)
{
Stream stream = File.Open(filename, FileMode.Create);
BinaryFormatter bFormatter = new BinaryFormatter();
bFormatter.Serialize(stream, objectToSerialize);
stream.Close();
}

public ObjectToSerialize DeSerializeObject(string filename)
{
ObjectToSerialize objectToSerialize;
Stream stream = File.Open(filename, FileMode.Open);
BinaryFormatter bFormatter = new BinaryFormatter();
objectToSerialize =
(ObjectToSerialize)bFormatter.Deserialize(stream);
stream.Close();
return objectToSerialize;
}
}
}

In our windows application our form contains 2 buttons.A serialize button and a deserialize button.

When we click serialize, all the 'jpg' files in a said folder will be serialized to one file.In our example we are also considering one condition.We assume that we already have a serialized version of our images.If we are making a new serialized file then the condition

if(count==1)
{}

can be ignored.The rest will do the job.

The button click event which does the serialization of the images is written as,


private void _serializeButton_Click(object sender, EventArgs e)
{
List imageList = new List();
ImageClass imageClass;

int count = 1;

DirectoryInfo directory = new DirectoryInfo("D:\\Serialize\\Temp");
///serializing all 'jpg' files in the
///temp folder of the directory.
foreach (FileInfo file in directory.GetFiles())
{
if (file.Name.Contains("jpg"))
{
///if we already have a serialized file in the directory then
///get the already existing images to the images list and
///then add the new image to the list.
///In our case we are adding files to already existing serialized
///file.If that is not required then the below given
///if condition can be ignored.
if (count == 1)
imageList = DeserializeImages();
imageClass = new ImageClass();
Image image = Image.FromFile(file.FullName);
imageClass.ImageName = file.Name;
imageClass.ImageObject = image;
imageList.Add(imageClass);
count++;
}
}

ObjectToSerialize objectToSerialize = new ObjectToSerialize();
objectToSerialize.Images = imageList;
Serializer serializer = new Serializer();
///the biggest advantage of serialization is that we can
///save a serialized file with any extension.
serializer.SerializeObject("D:\\Serialize\\imagesTemp.abc", objectToSerialize);
MessageBox.Show("Serialized");
}

Now we are going to display the images in an imagebox based on timer tick after we deserialize the images.

private void _deserializeButton_Click(object sender, EventArgs e)
{
List images = DeserializeImages();

_images = images;

Timer timer = new Timer();
timer.Enabled = true;
timer.Interval = 1000;
timer.Start();
_imageCount = 0;
timer.Tick += new EventHandler(timer_Tick);
}

private static List DeserializeImages()
{
List images = new List();
ObjectToSerialize objectToSerialize = new ObjectToSerialize();
objectToSerialize.Images = images;

Serializer serializer = new Serializer();
objectToSerialize = serializer.DeSerializeObject("D:\\Serialize\\imagesTemp.abc");
images = objectToSerialize.Images;
return images;
}

void timer_Tick(object sender, EventArgs e)
{
_imageCount++;
int imageCount = 0;
foreach (ImageClass cls in _images)
{
if (imageCount == _imageCount)
{
_imagelabel.Text = cls.ImageName;
_imageBox.Image = cls.ImageObject;
}
imageCount++;
}
}

This does the tricks.So now on each timer tick and image from the list will be displayed in the ImageBox.The image can be retrieved with the image name even from the list box.The various manipulations with this code are all based on your tactics.. I've just included a basic example with the images.

I hope this code might be of use to somebody or the other.To people who have no idea about serialization do develop some initial idea about serialization and then refer to this code.

Cheers..

7 comments:

adrian_lulea said...

Thanks man... I was searching for this for a long time... you a real life saver ;)

Now all I have to do is to modelate it in order to fill my needs.

Thanks again :)

Salu said...

Thanks..My Pleasure..

Anonymous said...

Thanks, but i cant find
The object "List"
what using except the one from the article do i need to control it?

Vimal Raj said...

Hi,
You can implement List as a generic Class and use it like

List<T> t = new List<T>();

Or you can create a non generic List class implementing IList interface.

chathuranga said...

Thanks very much for this info...can u send me or upload project (vs solution it'll help me more cause i'm new to c# coding stuffs and i unable to create project using your source code in blog. this is my email - ucsccbjp@gmail.com---thanks again

ursri said...

This method is perfect for object read/written with same structure. How best to implement/manage object changes while deserializing saved object of prev. structure? Pls suggest.

Leslie Lim said...


Really awesome blog. Your blog is really useful for me. Thanks for sharing this informative blog. Keep update your blog.

www.imarksweb.org