2016-02-27 68 views
0

我有一个图像类,根据图像嵌入或不嵌入的情况,必须(有时)序列化/反序列化。带图像的数据合同序列化/序列化

[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) 
    { 
    ... 
    } 

} 

所以问题是,尽管把

public Image ImageEmbedded = new Image(); 

ImageEmbedded总是空。 所以我把它放在一个构造像

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

,但是当我这样做,我得到一个序列化错误。 那我该怎么办? 我不会将图像转换为字节[]或其他。我选择Datacontract序列化我认为它可以serilize图像。 谢谢

+0

哪里它说的DataContractSerializer可以序列化图像? –

+0

那么datacontract串行器的优点是什么? – Luca

+0

比什么优势? –

回答

1

有一个在你的代码的一个重大问题:在WPF如果你序列化一个Image,你可以序列化System.Windows.Controls.Image。总之,序列化控件没有意义。相反,您可能需要序列化BitmapSource,但这里又不能序列化,因此您必须将它们转换为byte[],如前所述。

[DataMember] 
public byte[] bytesBitmapEmbedded; 

,然后简单地将其更改为的BitmapSource或字节[]通过这样的:

bytesBitmapEmbedded = Converter.BitmapSource2ByteArray(bitmapSource); 

bitmapSource = Converter.ByteArray2BitmapSource(bytesBitmapEmbedded); 

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

该作品谢谢!但请序列化/反序列化后,我失去了背景透明度。 – Luca

+1

很简单:不是使用BmpBitmapEncoder,而是使用PngBitmapEncoder – Patrick

0

如果你的编程器不直接知道如何转换字段的类型,那么你就会对抗风。更简单的解决方案是恢复到大多数语言的更原始类型;创建一个Data-Transfer Object。例如,我使用一些类似的存储1- 2维的数据相当多样化的量与protobuf.net(编辑为您的需要):

[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; } 
} 
你的情况

所以,你只需要处理图像格式枚举代码并从图像中获取二进制数据。见Fastest way to convert Image to Byte arrayWPF Image to byte[]https://github.com/teichgraf/WriteableBitmapEx/

然后,你可以简单地抛出这个ImageDTO到几乎大部分基于合约的串行器/解串器的任何实例。例如,如果你选择协议的缓冲区,在.NET土地可以用protobuf.net连载,而在JavaScript的土地可以用protobuf.js deserialise给出的.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; 
} 
+0

谢谢,所以如果我没有弄错它protobuf.net是一种不同类型的datacontract序列化?如果是这样,我想坚持标准的数据合同。在任何情况下,我试图改变图像 - >字节[]。然后尝试“最快的方式将图像转换为字节数组”链接。但这不是WPF! – Luca

+0

我已经添加了更多链接,提出这个问题WPF图像>字节。你可能会发现WriteableBitmapEx也会有一些访问方法来帮助你。 'protobuf.net'是一个合约串行器(可以使用DataContract属性),但它串行到协议缓冲区二进制格式。 –