【问题标题】:Wrap ImageSource for Base64 image serialization为 Base64 图像序列化包装 ImageSource
【发布时间】:2013-04-18 15:12:06
【问题描述】:

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

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

我稍微研究了 ImageSource 类,但我相信我对它的工作原理还不够了解。当我在自定义包装类中实现 ImageSource 时,我得到了 2 个我不清楚的方法:

  1. 元数据

  2. CreateInstanceCore

我想知道是否有人可以对这些方法有所了解,或者指出一个不会让我回到 MSDN 文档的方向。

【问题讨论】:

  • 为什么不在可执行文件或控件库的程序集中将图像作为嵌入资源?
  • 因为唯一持久化的数据是序列化的 XAML,而 XAML 序列化不能很好地处理图像。
  • 你可能想看看Implementing A Custom BitmapSource
  • 为什么要序列化视图而不是模型和/或视图模型?
  • 作为我第一次涉足 WPF,我没有使用 MVVM 设计模式。从那以后我读了一点,我明白了为什么我应该首先使用这种模式。我可能很快就会重新设计。

标签: c# wpf image


【解决方案1】:

这个类包装了一个从 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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-31
    • 2021-07-14
    • 2019-10-10
    • 1970-01-01
    • 1970-01-01
    • 2017-12-03
    相关资源
    最近更新 更多