如何解决是否可以保留用于构建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 举报,一经查实,本站将立刻删除。