简体   繁体   English

数据合同与图像的序列化/序列化

[英]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. ImageEmbedded始终为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. 我不会将Image转换为byte []或其他。 I have chosen Datacontract serialization for I thought that it could serilize images. 我选择Datacontract序列化是因为我认为它可以对图像进行序列化。 Thank you 谢谢

There is a major problem in your code: in WPF if you serialize an Image you serialize System.Windows.Controls.Image. 代码中存在一个主要问题:在WPF中,如果序列化Image,则序列化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. 相反,您可能想要序列化BitmapSource但是在这里再次无法序列化,因此您必须将它们转换为byte[]

[DataMember]
public byte[] bytesBitmapEmbedded;

and then simply change it to BitmapSource or byte[] through this: 然后只需将其更改为BitmapSource或byte []:

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

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): 例如,我使用protobuf.net使用类似以下内容(根据您的需要进行编辑)存储了大量的1-二维数据:

[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/ 请参阅将图像转换为字节数组或将WPF图像 转换为字节的最快方法 []https://github.com/teichgraf/WriteableBitmapEx/

Then you can simply throw any instance of this ImageDTO to pretty much most Contract-based serialisers / deserialisers. 然后,您可以简单地将此ImageDTO任何实例ImageDTO几乎所有基于合约的序列化器/反序列化器。 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 例如,如果选择协议缓冲区,则在.net区域中可以使用protobuf.net进行序列 ,而在javascript区域中,可以使用protobuf.js进行反序列化(给定.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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM