2013-04-18 31 views
0

我有一个包含图像面板的WPF控件。我试图序列化,以便它可以独立加载,而不必在本地文件夹中有图像。包装BaseS图像序列化ImageSource

我知道我可以将图像存储为Base64字符串,然后可能加载备份,但我想要做的是包装ImageSource类以接受Base64字符串作为源。

我看了一下ImageSource类,我相信我对它的工作原理知之甚少。当我在我的自定义包装类实现的ImageSource我得到2种方法,我很清楚的:

  1. CreateInstanceCore

我想知道如果有人能提供一些线索在这些方法上,或者指向一个不会让我回到MSDN文档的方向。

+0

为什么不只是在装配时的图像作为嵌入资源你的可执行文件或控制库? – Clemens

+0

由于持久化的唯一数据是序列化的XAML,并且XAML序列化不能很好地与图像配合使用。 – Gianni

+0

您可能想要查看[实现自定义BitmapSource](http://blogs.msdn.com/b/dwayneneed/archive/2008/06/20/implementing-a-custom-bitmapsource.aspx)。 – Clemens

回答

3

该类包装是从一个base64字符串属性初始化的BitmapImage:

public class Base64BitmapImage : BitmapSource 
{ 
    private BitmapImage bitmap; 
    private string base64Source; 

    public string Base64Source 
    { 
     get { return base64Source; } 
     set 
     { 
      base64Source = value; 
      bitmap = new BitmapImage(); 

      if (DecodeFailed != null) 
      { 
       bitmap.DecodeFailed += DecodeFailed; 
      } 

      using (var stream = new MemoryStream(Convert.FromBase64String(base64Source))) 
      { 
       bitmap.BeginInit(); 
       bitmap.CacheOption = BitmapCacheOption.OnLoad; 
       bitmap.StreamSource = stream; 
       bitmap.EndInit(); 
      } 

      if (DecodeFailed != null) 
      { 
       bitmap.DecodeFailed -= DecodeFailed; 
      } 

      bitmap.Freeze(); 
     } 
    } 

    public override event EventHandler<ExceptionEventArgs> DecodeFailed; 

    public override bool IsDownloading 
    { 
     get { return false; } 
    } 

    public override PixelFormat Format 
    { 
     get { return bitmap != null ? bitmap.Format : base.Format; } 
    } 

    public override double DpiX 
    { 
     get { return bitmap != null ? bitmap.DpiX : base.DpiX; } 
    } 

    public override double DpiY 
    { 
     get { return bitmap != null ? bitmap.DpiY : base.DpiY; } 
    } 

    public override double Width 
    { 
     get { return bitmap != null ? bitmap.Width : base.Width; } 
    } 

    public override double Height 
    { 
     get { return bitmap != null ? bitmap.Height : base.Height; } 
    } 

    public override int PixelWidth 
    { 
     get { return bitmap != null ? bitmap.PixelWidth : base.PixelWidth; } 
    } 

    public override int PixelHeight 
    { 
     get { return bitmap != null ? bitmap.PixelHeight : base.PixelHeight; } 
    } 

    public override ImageMetadata Metadata 
    { 
     get { return bitmap != null ? bitmap.Metadata : base.Metadata; } 
    } 

    public override void CopyPixels(Array pixels, int stride, int offset) 
    { 
     if (bitmap != null) 
     { 
      bitmap.CopyPixels(pixels, stride, offset); 
     } 
    } 

    public override void CopyPixels(Int32Rect sourceRect, Array pixels, int stride, int offset) 
    { 
     if (bitmap != null) 
     { 
      bitmap.CopyPixels(sourceRect, pixels, stride, offset); 
     } 
    } 

    public override void CopyPixels(Int32Rect sourceRect, IntPtr buffer, int bufferSize, int stride) 
    { 
     if (bitmap != null) 
     { 
      bitmap.CopyPixels(sourceRect, buffer, bufferSize, stride); 
     } 
    } 

    protected override Freezable CreateInstanceCore() 
    { 
     var instance = new Base64BitmapImage(); 
     instance.bitmap = bitmap; 
     instance.base64Source = base64Source; 
     return instance; 
    } 
} 

它可以使用这样的:

<Image> 
    <Image.Source> 
     <local:Base64BitmapImage Base64Source="..."/> 
    </Image.Source> 
</Image>