我正在制作一个C#/ WPF / Windows 8应用程序商店应用程序,我正在尝试加载一些PNG / JPG以在视图中显示它们。图像都是相当高的分辨率,但文件大小通常只有大约200k左右。问题是,当我使用BitmapImage类(这是我能找到的唯一一个)加载它们时,使用的总内存会跳升到100s megs。据我所知,它需要png / jpb并将其转换为位图图像,这大大增加了内存使用量。到目前为止,我还没有找到解决方法,尽管似乎应该有一个简单的解决方案。
有什么东西真的很明显我不见了吗?
我的代码
private async Task TestFunction(IReadOnlyList<StorageFile> files)
{
var images = new ObservableCollection<Image>();
imagePanel.ItemsSource = coverImages;
foreach (var file in files)
{
var bitmap = new BitmapImage();
var item = await file.OpenAsync(FileAccessMode.Read);
bitmap.SetSource(item);
var image = new Image();
image.Source = bitmap;
image.Height = 200;
images.Add(image);
}
}
答案 0 :(得分:7)
如果磁盘上的图像采用压缩格式(并且大多数图像文件格式使用某种形式的压缩),则内存占用空间会更大。
如果图像的大小为100x100像素,并且使用8位作为颜色深度,则该图像的原始数据将占用100x100 = 10,000字节,这就是必须呈现到屏幕的数据量。
如果您正在寻找一种方法来减少WPF应用程序中的memorty使用情况,您可以尝试一些选项。
请勿将图像缓存在内存中,或选择最佳时间
使用BitmapCacheOption
加载图片,例如:bitmap.CacheOption = BitmapCacheOption.None
这将根据需要从磁盘填充图像,如果图像只有200k,性能下降不应该太差,但它不会像缓存那么快
确保您不会渲染大于他们需要的图像,如果
您正在显示图像的Element
是200x200和图像
是1024x768你可以设置DecodePixelWidth
,这将创建
Bitmap
为您定义的大小而不是实际大小。
例如:bitmap.DecodePixelWidth = 200
答案 1 :(得分:3)
PNG,JPG和所有其他形式的图像压缩仅对存储有用。为了在WPF中显示压缩图像内容,您必须将其解压缩为Bitmap,这是图像数据的原始一对一表示。
如果您不将解压缩的图像数据存储在内存中,那么每次系统尝试引用图像进行显示时,都必须使用宝贵的CPU资源再次解压缩图像。对于像PNG或JPG这样的流行格式,压缩和解压缩过程相当复杂。
有图像压缩格式,专为动态解压缩而设计。但是,这些格式(例如DXT1-5)通常仅由3D库支持。 (more info here)