微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

是否可以保留用于构建BitmapImage的原始数据而无需重新编码?

如何解决是否可以保留用于构建BitmapImage的原始数据而无需重新编码?

再详细说明标题,我们有一些代码可以从磁盘加载图像文件,然后将其转换为BitmapImage以在屏幕上显示。然后,我们需要将该数据作为字节数组保留到其他存储机制中,以便以后可以按原样重新加载。

问题是,据我了解,要将BitmapImage转换回字节数组,必须使用编码器,但是如果使用编码器,则每次保存时都要重新编码图像因此,除非您使用无损格式,否则可能会降低图像质量,但是使用无损格式意味着您可能会将jpeg数据等存储空间加倍。

我的想法是创建一个“持有人”类型来保存原始的原始数据(同样是从jpg文件获取),然后使用它来按需创建BitmapImage并将其缓存以备将来检索。

到目前为止,这就是我所说的“持有人”类型。 (请注意隐式转换器,因此我可以在接受BitmapImage的任何地方使用它):

#nullable enable

class PersistableBitmapImage{

    public PersistableBitmapImage(byte[] bytes)
        => _bytes = bytes;

    private byte[] _bytes;
    public byte[] Bytes {
        get => _bytes;
        set{
            _bytes = value;
            _bitmapImage = null;
        }
    }

    private BitmapImage? _bitmapImage;
    public BitmapImage BitmapImage
        => _bitmapImage ?? (_bitmapImage = Bytes.MakeBitmapImage());

    #region Implicit Operators

        public static implicit operator BitmapImage(PersistableBitmapImage persistableBitmapImage)
            => persistableBitmapImage.BitmapImage;

    #endregion Implicit Operators
}

以下是用于创建BitmapImage的帮助程序扩展名:

public static class ByteArrayExtensions {

    public static BitmapImage MakeBitmapImage(this byte[] bytes){

        using var ms = new MemoryStream(bytes);

        var bitmapImage = new BitmapImage();

        bitmapImage.BeginInit();
            bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
            bitmapImage.StreamSource = ms;
        bitmapImage.EndInit();

        return bitmapImage;
    }
}

这种设计的问题是在访问BitmapImage的情况下,我现在两次保存图像数据,一次是压缩格式(Data属性),另一次是已实现/扩展的BitmapImage属性。唯一的好处是,只有在访问了后者的情况下,后者才会被“实现”,而压缩的前者是持久存在的东西。

还是让我有点“讨厌”。有没有一种方法可以不用两次保存图像数据?

解决方法

您可以避免在此处处置MemoryStream(处置MemoryStream的做法尽管没有做任何有趣的事情,也没有资源可处置):

using var ms = new MemoryStream(bytes);

然后可以通过访问bitmapImage.StreamSource来访问相同的内存流。请注意,返回的流Position可能不是0,因为BitmapImage可能已经读过它,因此请不要忘记在必要时将位置重置为0。通常,调用MemoryStream.GetBuffer()(最好使用ToArray())是个坏主意,但是在这种特殊情况下,避免不必要的复制可能是适当的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。