【发布时间】:2021-02-12 14:47:08
【问题描述】:
稍微详细说明一下标题,我们有一些代码可以从磁盘加载图像文件,然后将其转换为BitmapImage 以显示在屏幕上。然后我们需要将该数据作为字节数组保存到不同的存储机制中,以便以后可以按原样重新加载。
据我了解,问题在于,要将 BitmapImage 转换回字节数组,您必须使用编码器,但如果您使用编码器,则每次保存时都会重新编码图像,除非如果您使用无损格式,则可能会降低图像质量,但不使用无损格式意味着您可能会将存储空间翻倍,而不是 jpeg 数据。
我的想法是创建一个 'holder' 类型来保存原始的原始数据(同样,例如来自 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 属性),另一次是已实现/扩展的 @ 987654331@ 财产。唯一的好处是后者只有在访问时才会“实现”,而压缩的前者是持久化的。
我还是觉得有点“恶心”。有没有办法在不保存图像数据两次的情况下做到这一点?
【问题讨论】:
-
我完全不懂这个问题。如果您想将位图“保留”在其原始形式中,为什么不在第一次加载位图时复制原始数据?您要在这里解决的实际问题是什么?你的问题写满了XY Problem。 :( Stack Overflow 无法有效地回答唯一陈述的问题是“icky”的问题。
-
你需要那个属性吗?你能用返回
MakeBitmapImage()结果的方法来代替它吗? -
bitmapImage.StreamSource属性怎么样?它有吸气剂,我希望它存储您传递给它的原始内存流,然后您可以访问并取回您的字节数组(可能首先需要将位置重置为 0,因为 BitmapImage 已读取它) -
如果确实需要属性,则不需要支持字段。
-
@PeterDuniho,这正是我上面的解决方案所做的......它保留了原始图像数据,专门为存储而预解压缩。
标签: c# arrays wpf bitmapimage encoder