LEADTOOLS For .NET Class Library Send comments on this topic. | Back to Introduction - All Topics | Help Version 17.0.3.28
RasterImage Serialization

Introduction

Binary Serialization

XML Serialization

Deriving from RasterImage and Serialization

Introduction

The RasterImage interface and the RasterImage class implement the ISerializable interface and thus support standard .NET serialization.

Serialization is the process of converting the state of an object into a form that can be persisted or transported. The complement of serialization is deserialization, which converts a stream into an object. Together, these processes allow data to be easily stored and transferred.

You can easily save and restore the image data of a RasterImage object by saving/loading the image back into one of the numerous file image formats supported by LEADTOOLS. However, by doing so, you lose any data that is not supported by the image file format. For example, the region data you currently have in the image is not supported by any file image format. The metadata (tags, markers and comments) are supported by some formats but not all.

Serialization solves these problems by saving everything in the image and later deserializing back into its original state. Moreover, when you derive your own class from RasterImage, you can extend the serialization mechanism to support saving/restoring your own data inside the image.

The RasterImage supports both binary and XML serialization.

Binary Serialization

You can use binary serialization to share the RasterImage object between different applications by serializing it to the Clipboard. You can serialize the RasterImage to a stream, to a disk, to memory, over the network, and so forth. Remoting uses binary serialization to pass objects "by value" from one computer or application domain to another.

Binary serialization is the most efficient way to serialize a RasterImage object both in speed of serialization/deserialization as well using less space for the object data.

Examples of binary serialization:

[Visual Basic]
            Imports System.IO
            Imports System.Runtime.Serialization.Formatters.Binary
            Imports Leadtools
            Imports Leadtools.Codecs
            
            Private Sub BinarySerializationTest()
                Dim codecs As RasterCodecs = New RasterCodecs()
                
                ' Load an image
                Dim image1 As RasterImage = codecs.Load("C:\Users\Public\Documents\LEADTOOLS Images\Image1.cmp")
                
                ' Use the binary formatter
                Dim formatter As BinaryFormatter = New BinaryFormatter()
                
                ' Serialize this image into a memory stream
                Dim ms As MemoryStream = New MemoryStream()
                formatter.Serialize(ms, image1)
                
                ' We are done with the image
                image1.Dispose()
                
                ' Move back to the beginning of the stream
                ms.Position = 0
                
                ' De-serialize the image back
                Dim image2 As RasterImage = CType(If(TypeOf formatter.Deserialize(ms) Is RasterImage, formatter.Deserialize(ms), Nothing), RasterImage)
                
                ' re-save the image
                codecs.Save(image2, "C:\Users\Public\Documents\LEADTOOLS Images\Image1_Serialized.bmp", RasterImageFormat.Bmp, 24)
                
                ' Clean up
                image2.Dispose()
                ms.Close()
                
                codecs.Dispose()
            End Sub
            
[C#]
            using System.IO;
            using System.Runtime.Serialization.Formatters.Binary;
            using Leadtools;
            using Leadtools.Codecs;
            
            private void BinarySerializationTest()
            {
                RasterCodecs codecs = new RasterCodecs();
                
                // Load an image
                RasterImage image1 = codecs.Load(@"C:\Users\Public\Documents\LEADTOOLS Images\Image1.cmp");
                
                // Use the binary formatter
                BinaryFormatter formatter = new BinaryFormatter();
                
                // Serialize this image into a memory stream
                MemoryStream ms = new MemoryStream();
                formatter.Serialize(ms, image1);
                
                // We are done with the image
                image1.Dispose();
                
                // Move back to the beginning of the stream
                ms.Position = 0;
                
                // De-serialize the image back
                RasterImage image2 = formatter.Deserialize(ms) as RasterImage;
                
                // re-save the image
                codecs.Save(image2, @"C:\Users\Public\Documents\LEADTOOLS Images\Image1_Serialized.bmp", RasterImageFormat.Bmp, 24);
                
                // Clean up
                image2.Dispose();
                ms.Close();
                
                codecs.Dispose();
            }
            

XML serialization

You can also use serialize a RasterImage object to XML. Since XML is an open standard, XML serialization is an attractive choice for sharing a RasterImage object across the Web.

However, since XML is a text format, XML serialization is not recommended to be used with a RasterImage object. The speed of serialization/deserialization is a lot slower than binary serialization and XML serialization uses a lot more space for the object data.

Serialization Example (Using the Windows Clipboard)

The following example shows you how to copy and paste a RasterImage object to the Windows clipboard using serialization. This example assumes that you have added the code to a Form and call the method created in the example from the constructor or another method on the form.

[Visual Basic]
            Imports System
            Imports System.Windows.Forms
            Imports Leadtools
            Imports Leadtools.Codecs
            Imports Leadtools.WinForms
            
            Private panel1 As Panel
            Private loadButton As Button
            Private clearButton As Button
            Private copyButton As Button
            Private pasteButton As Button
            Private rasterImageViewer1 As RasterImageViewer
            Private codecs1 As RasterCodecs
            
            Private Sub ClipboardTest()
               ' Add the controls to the form
               ' 1. RasterImageViewer control
               ' 2. Load button to load an image into the viewer
               ' 3. Clear button to reset the viewer's image.
               ' 3. Copy button to copy the image to the clipboard
               ' 4. Paste button to paste the image from the clipboard to the viewer
            
               ' Create the controls
            
               Me.SuspendLayout()
            
               loadButton = New Button
            
               panel1 = New Panel
               panel1.Dock = DockStyle.Left
               panel1.Width = loadButton.Width
               Me.Controls.Add(panel1)
            
               loadButton.Text = "Load"
               loadButton.Location = New Point(0, 0)
               panel1.Controls.Add(loadButton)
               loadButton.BringToFront()
               AddHandler loadButton.Click, AddressOf loadButton_Click
            
               clearButton = New Button
               clearButton.Text = "Clear"
               clearButton.Location = New Point(0, loadButton.Bottom)
               panel1.Controls.Add(clearButton)
               clearButton.BringToFront()
               AddHandler clearButton.Click, AddressOf clearButton_Click
            
               copyButton = New Button
               copyButton.Text = "Copy"
               copyButton.Location = New Point(0, clearButton.Bottom)
               panel1.Controls.Add(copyButton)
               copyButton.BringToFront()
               AddHandler copyButton.Click, AddressOf copyButton_Click
            
               pasteButton = New Button
               pasteButton.Text = "Paste"
               pasteButton.Location = New Point(0, copyButton.Bottom)
               panel1.Controls.Add(pasteButton)
               pasteButton.BringToFront()
               AddHandler pasteButton.Click, AddressOf pasteButton_Click
            
               rasterImageViewer1 = New RasterImageViewer
               rasterImageViewer1.Dock = DockStyle.Fill
               Controls.Add(rasterImageViewer1)
               rasterImageViewer1.BringToFront()
            
               Me.ResumeLayout()
            
               ' Initialize the codecs object
               codecs1 = New RasterCodecs
            
               ' Update our user interface
               UpdateMyUserInterface()
            End Sub
            
            Private Sub UpdateMyUserInterface()
               ' Update the buttons depending on the application state
            
               ' The Clear button is enabled if we have an image
               clearButton.Enabled = (Not rasterImageViewer1.Image Is Nothing)
            
               ' The Copy button is enabled if we have an image
               copyButton.Enabled = (Not rasterImageViewer1.Image Is Nothing)
            
               ' The paste button is enabled if we have a valid clipboard format
               Dim data As IDataObject = Clipboard.GetDataObject()
               pasteButton.Enabled = data.GetDataPresent(GetType(RasterImage))
            End Sub
            
            Private Sub loadButton_Click(ByVal sender As Object, ByVal e As EventArgs)
               ' Load a new image into the viewer
               Dim dlg As New OpenFileDialog
               dlg.Filter = "All Files|*.*"
               If (dlg.ShowDialog(Me) = DialogResult.OK) Then
                  Try
                     rasterImageViewer1.Image = codecs1.Load(dlg.FileName)
                  Catch ex As Exception
                     MessageBox.Show(Me, ex.Message)
                  Finally
                  ' Update the user interface
                  UpdateMyUserInterface()
                  End Try
               End If
            End Sub
            
            Private Sub clearButton_Click(ByVal sender As Object, ByVal e As EventArgs)
               ' Delete the image in the viewer
               rasterImageViewer1.Image = Nothing
            
               ' Update the user interface
               UpdateMyUserInterface()
            End Sub
            
            Private Sub copyButton_Click(ByVal sender As Object, ByVal e As EventArgs)
               ' Copy the image in the viewer into the clipboard
               Clipboard.SetDataObject(rasterImageViewer1.Image, True)
            
               ' Update the user interface
               UpdateMyUserInterface()
            End Sub
            
            Private Sub pasteButton_Click(ByVal sender As Object, ByVal e As EventArgs)
               ' Paste the image from the clipboard into the viewer
               Dim data As IDataObject = Clipboard.GetDataObject()
               rasterImageViewer1.Image = CType(data.GetData(GetType(RasterImage)), RasterImage)
            
               ' Update the user interface
               UpdateMyUserInterface()
            End Sub
            
[C#]
            using System;
            using System.Windows.Forms;
            using Leadtools;
            using Leadtools.Codecs;
            using Leadtools.WinForms;
            
            private Panel panel1;
            private Button loadButton;
            private Button clearButton;
            private Button copyButton;
            private Button pasteButton;
            private RasterImageViewer rasterImageViewer1;
            private RasterCodecs codecs1;
            
            private void ClipboardTest()
            {
               // Add the controls to the form
               // 1. RasterImageViewer control
               // 2. Load button to load an image into the viewer
               // 3. Clear button to reset the viewer's image.
               // 3. Copy button to copy the image to the clipboard
               // 4. Paste button to paste the image from the clipboard to the viewer
            
               // Create the controls
            
               this.SuspendLayout();
            
               loadButton = new Button();
            
               panel1 = new Panel();
               panel1.Dock = DockStyle.Left;
               panel1.Width = loadButton.Width;
               this.Controls.Add(panel1);
            
               loadButton.Text = "Load";
               loadButton.Location = new Point(0, 0);
               panel1.Controls.Add(loadButton);
               loadButton.BringToFront();
               loadButton.Click += new EventHandler(loadButton_Click);
            
               clearButton = new Button();
               clearButton.Text = "Clear";
               clearButton.Location = new Point(0, loadButton.Bottom);
               panel1.Controls.Add(clearButton);
               clearButton.BringToFront();
               clearButton.Click += new EventHandler(clearButton_Click);
            
               copyButton = new Button();
               copyButton.Text = "Copy";
               copyButton.Location = new Point(0, clearButton.Bottom);
               panel1.Controls.Add(copyButton);
               copyButton.BringToFront();
               copyButton.Click += new EventHandler(copyButton_Click);
            
               pasteButton = new Button();
               pasteButton.Text = "Paste";
               pasteButton.Location = new Point(0, copyButton.Bottom);
               panel1.Controls.Add(pasteButton);
               pasteButton.BringToFront();
               pasteButton.Click += new EventHandler(pasteButton_Click);
            
               rasterImageViewer1 = new RasterImageViewer();
               rasterImageViewer1.Dock = DockStyle.Fill;
               Controls.Add(rasterImageViewer1);
               rasterImageViewer1.BringToFront();
            
               this.ResumeLayout();
            
               // Initialize the codecs object
               codecs1 = new RasterCodecs();
            
               // Update our user interface
               UpdateMyUserInterface();
            }
            
            private void UpdateMyUserInterface()
            {
               // Update the buttons depending on the application state
            
               // The Clear button is enabled if we have an image
               clearButton.Enabled = rasterImageViewer1.Image != null;
            
               // The Copy button is enabled if we have an image
               copyButton.Enabled = rasterImageViewer1.Image != null;
            
               // The paste button is enabled if we have a valid clipboard format
               IDataObject data = Clipboard.GetDataObject();
               pasteButton.Enabled = data.GetDataPresent(typeof(RasterImage));
            }
            
            private void loadButton_Click(object sender, EventArgs e)
            {
               // Load a new image into the viewer
               OpenFileDialog dlg = new OpenFileDialog();
               dlg.Filter = "All Files|*.*";
               if(dlg.ShowDialog(this) == DialogResult.OK)
               {
                  try
                  {
                     rasterImageViewer1.Image = codecs1.Load(dlg.FileName);
                  }
                  catch(Exception ex)
                  {
                     MessageBox.Show(this, ex.Message);
                  }
                  finally
                  {
                     // Update the user interface
                     UpdateMyUserInterface();
                  }
               }
            }
            
            private void clearButton_Click(object sender, EventArgs e)
            {
               // Delete the image in the viewer
               rasterImageViewer1.Image = null;
            
               // Update the user interface
               UpdateMyUserInterface();
            }
            
            private void copyButton_Click(object sender, EventArgs e)
            {
               // Copy the image in the viewer into the clipboard
               Clipboard.SetDataObject(rasterImageViewer1.Image, true);
            
               // Update the user interface
               UpdateMyUserInterface();
            }
            
            private void pasteButton_Click(object sender, EventArgs e)
            {
               // Paste the image from the clipboard into the viewer
               IDataObject data = Clipboard.GetDataObject();
               rasterImageViewer1.Image = data.GetData(typeof(RasterImage)) as RasterImage;
            
               // Update the user interface
               UpdateMyUserInterface();
            }
            

Deriving from RasterImage and Serialization

The RasterImage class can be derived from to add user-defined functionality. Derived classes might need to add new class member variables to the class that define this new functionality. The author must add support for serializing these new class member variables in order to participate in the serialization process.

The following example shows MyRasterImage, a class that derives from RasterImage adding two new properties.

[Visual Basic]
            Imports System.IO
            Imports System.Runtime.Serialization
            Imports System.Runtime.Serialization.Formatters.Binary
            Imports Leadtools
            Imports Leadtools.Codecs
            
            Public Class MyRasterImage
               Inherits RasterImage
               ' Our new members
               ' We are going to do the serialization ourselves
               Private _myIntegerData As Integer
               Private _myStringData As String
            
               ' Accessors
               Public Property MyIntegerData() As Integer
                  Get
                      Return _myIntegerData
                  End Get
                  Set(ByVal Value As Integer)
                     _myIntegerData = Value
                  End Set
               End Property
            
               Public Property MyStringData() As String
                  Get
                     Return _myStringData
                  End Get
                  Set(ByVal Value As String)
                     _myStringData = Value
                  End Set
               End Property
            
               ' Constructor
               Public Sub New(ByVal src As RasterImage)
                  MyBase.New(src)
            
                  _myIntegerData = 0
                  _myStringData = String.Empty
               End Sub
            
               ' Serialization code
               Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
                  MyBase.New(info, context)
            
                  ' Load our data
                  _myIntegerData = info.GetInt32("MyIntegerData")
                  _myStringData = info.GetString("MyStringData")
               End Sub
            
               Public Overrides Sub GetObjectData(ByVal info As SerializationInfo, ByVal context As StreamingContext)
                  ' Always call the base method
                  MyBase.GetObjectData(info, context)
            
                  ' Save our data
                  info.AddValue("MyIntegerData", _myIntegerData)
                  info.AddValue("MyStringData", _myStringData)
               End Sub
            End Class
            
            Private Sub MyRasterImageTest()
               ' Load an image
               Dim codecs As New RasterCodecs
            
               Dim img As RasterImage = codecs.Load("C:\Users\Public\Documents\LEADTOOLS Images\Image1.cmp")
            
               ' create a new MyRasterImage instance out of this image
               Dim myImage As MyRasterImage = New MyRasterImage(img)
            
               ' Set our custom data
               myImage.MyIntegerData = 10
               myImage.MyStringData = "My string"
               Dim msg As String = String.Format("Before serialization.  MyIntegerData = {0}, MyStringData = {1}", myImage.MyIntegerData, myImage.MyStringData)
               MessageBox.Show(msg)
            
               ' img is inavlid now and shoule be disposed
               img.Dispose()
            
               ' Serialize myImage
               Dim formatter As New BinaryFormatter
               Dim ms As New MemoryStream
               formatter.Serialize(ms, myImage)
            
               ' dispose myImage
               myImage.Dispose()
               myImage = Nothing
            
               ' Deserialize back from the stream
               ms.Position = 0
               myImage = DirectCast(formatter.Deserialize(ms), MyRasterImage)
            
               msg = String.Format("After serialization.  MyIntegerData = {0}, MyStringData = {1}", myImage.MyIntegerData, myImage.MyStringData)
               MessageBox.Show(msg)
            
               ' Clean up
               ms.Close()
               myImage.Dispose()
               codecs.Dispose()
            End Sub
            
[C#]
            using System.IO;
            using System.Runtime.Serialization;
            using System.Runtime.Serialization.Formatters.Binary;
            using Leadtools;
            using Leadtools.Codecs;
            
            [Serializable]
            public class MyRasterImage : RasterImage
            {
               // Our new members
               // We are going to do the serialization ourselves
               [NonSerialized] private int _myIntegerData;
               [NonSerialized] private string _myStringData;
            
               // Accessors
               public int MyIntegerData
               {
                  get
                  {
                     return _myIntegerData;
                  }
                  set
                  {
                     _myIntegerData = value;
                  }
               }
            
               public string MyStringData
               {
                  get
                  {
                     return _myStringData;
                  }
                  set
                  {
                     _myStringData = value;
                  }
               }
            
               // Constructor
               public MyRasterImage(RasterImage src) :
               base(src)
               {
                  _myIntegerData = 0;
                  _myStringData = string.Empty;
               }
            
               // Serialization code
               protected MyRasterImage(SerializationInfo info, StreamingContext context) :
               base(info, context)
               {
                  // Load our data
                  _myIntegerData = info.GetInt32("MyIntegerData");
                  _myStringData = info.GetString("MyStringData");
               }
            
               public override void GetObjectData(SerializationInfo info, StreamingContext context)
               {
                  // Always call the base method
                  base.GetObjectData(info, context);
            
                  // Save our data
                  info.AddValue("MyIntegerData", _myIntegerData);
                  info.AddValue("MyStringData", _myStringData);
               }
            }
            
            private void MyRasterImageTest()
            {
               // Load an image
               RasterCodecs codecs = new RasterCodecs();
            
               RasterImage img = codecs.Load(@"C:\Users\Public\Documents\LEADTOOLS Images\Image1.cmp");
            
               // create a new MyRasterImage instance out of this image
               MyRasterImage myImage = new MyRasterImage(img);
            
               // Set our custom data
               myImage.MyIntegerData = 10;
               myImage.MyStringData = "My string";
               string msg = string.Format("Before serialization.  MyIntegerData = {0}, MyStringData = {1}", myImage.MyIntegerData, myImage.MyStringData);
               MessageBox.Show(msg);
            
               // img is inavlid now and shoule be disposed
               img.Dispose();
            
               // Serialize myImage
               BinaryFormatter formatter = new BinaryFormatter();
               MemoryStream ms = new MemoryStream();
               formatter.Serialize(ms, myImage);
            
               // dispose myImage
               myImage.Dispose();
               myImage = null;
            
               // Deserialize back from the stream
               ms.Position = 0;
               myImage = formatter.Deserialize(ms) as MyRasterImage;
            
               msg = string.Format("After serialization.  MyIntegerData = {0}, MyStringData = {1}", myImage.MyIntegerData, myImage.MyStringData);
               MessageBox.Show(msg);
            
               // Clean up
               ms.Close();
               myImage.Dispose();
               codecs.Dispose();
            }