Datacontract serialization/serialization with images

给你一囗甜甜゛ 提交于 2019-12-12 01:43:17

问题


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


回答1:


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);
        }
    }
}



回答2:


If your serialiser doesn't directly know how to convert a field's type then you'll be fighting against the wind. The easier solution is to revert to more primitive types that are in most languages; create a Data-Transfer Object. For example, I store quite a diverse amount of 1- 2-dimensional data with protobuf.net using something similar to this (edited for your needs):

[DataContract]
class ImageDTO
{
    [DataMember(Order = 1)]
    public int Width { get; set; }

    [DataMember(Order = 2)]
    public int Height { get; set; }

    [DataMember(Order = 3)]
    public ImageFormat Format { get; set; }

    [DataMember(Order = 4)]
    public byte[] Data { get; set; }

    [DataMember(Order = 5)]
    public string AltUrl { get; set; }
}

So in your case, you'd simply need to deal with the image format enum code and get the binary data from an image. See Fastest way to convert Image to Byte array OR WPF Image to byte[] OR https://github.com/teichgraf/WriteableBitmapEx/

Then you can simply throw any instance of this ImageDTO to pretty much most Contract-based serialisers / deserialisers. For example, if you choose protocol-buffers, in .net land you can serialise with protobuf.net, while in javascript land you can deserialise with protobuf.js given the .proto

message ImageDTO {
   optional int32 Width = 1 [default = 0];
   optional int32 Height = 2 [default = 0];
   optional ImageFormat Format = 3 [default = RGB];
   optional bytes Data = 4;
   optional string AltUrl = 5;
}
enum ImageFormat {
   RGB = 0;
   RGBA = 1;
   PNG = 2;
   JPEG = 3;
}


来源:https://stackoverflow.com/questions/35671829/datacontract-serialization-serialization-with-images

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!