Search code examples
c#wpfimagedatacontractserializer

Datacontract serialization/serialization with images


I have a class with an image that has to be (sometimes) serialized/deserialized according to the fact that the image is embedded or not.

[DataContract(IsReference = true)]
public class Data
{
  [DataContract(IsReference = true)]
  public class MyImage
  {

  [DataMember]
  int WidthStorage
  [DataMember]
  int HeightStorage;

  [DataMember]
  public string strImageLocation;
  [DataMember]
  public Image ImageEmbedded = new Image();<----- not working null
  public bool GetImage(Image image, int width, int height)
  {
    ...
  }

  public void SetImageFSlocation(string _strImageLocation, int _widthStorage, int _heightStorage)
  {
    ...        
  }

  public void SetImageEmbedded(string strPathFilename, int _widthStorage, int _heightStorage)
  {
    ...
  }

}

So the problem is that despite putting

public Image ImageEmbedded = new Image();

ImageEmbedded is always null. So I put it in a constructor like

[DataContract(IsReference = true)]
  public class MyImage
  {
    public MyImage()
    {
      ImageEmbedded = new Image();
    }
    ...

but when I do that I get a serialization error. So what have I got to do? I would NOT turn Image to byte[] or other. I have chosen Datacontract serialization for I thought that it could serilize images. Thank you


Solution

  • There is a major problem in your code: in WPF if you serialize an Image you serialize System.Windows.Controls.Image. So in short it doesn't make sense to serialize a control. Instead you might want to serialize a BitmapSource but here again those can't be serialized so you have to turn them to byte[] as already said.

    [DataMember]
    public byte[] bytesBitmapEmbedded;
    

    and then simply change it to BitmapSource or byte[] through this:

    bytesBitmapEmbedded = Converter.BitmapSource2ByteArray(bitmapSource);
    

    or

    bitmapSource = Converter.ByteArray2BitmapSource(bytesBitmapEmbedded);
    

    with

    public static class Converter
    {
        public static byte[] BitmapSource2ByteArray(BitmapSource bitmap)
        {
            using (var stream = new MemoryStream())
            {
                var encoder = new PngBitmapEncoder();
                encoder.Frames.Add(BitmapFrame.Create(bitmap));
                encoder.Save(stream);
                return stream.ToArray();
            }
        }
    
        public static BitmapSource ByteArray2BitmapSource(byte[] buffer)
        {
            using (var stream = new MemoryStream(buffer))
            {
                return BitmapFrame.Create(stream,
                    BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
            }
        }
    }