在最近的项目中,遇到一个关于WPF中同时加载多张图片时,内存占用非常高的问题。

问题背景:

在一个ListView中同时加载多张图片,注意:我们需要加载的图片分辨率非常高。

代码:

XAML:

    <Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions> <Button Content="Load" Width="100" Height="35" Margin="0,10" Click="Button_Click"/> <ListView Grid.Row="1" x:Name="lvImages">
<ListView.ItemTemplate>
<DataTemplate>
<Image Source="{Binding ImageSource}" MaxWidth="800"/>
</DataTemplate>
</ListView.ItemTemplate> <ListView.Template>
<ControlTemplate>
<Grid>
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Hidden">
<ItemsPresenter />
</ScrollViewer>
</Grid>
</ControlTemplate>
</ListView.Template> <ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel IsItemsHost="True" VirtualizingPanel.VirtualizationMode="Recycling" VirtualizingPanel.IsVirtualizing="True"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
</Grid>

C#:

    public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
} private void Button_Click(object sender, RoutedEventArgs e)
{
lvImages.Items.Clear(); // Image folder location: D:\Pics string[] files = System.IO.Directory.GetFiles(@"D:\Pics"); List<ImageSourceModel> models = new List<ImageSourceModel>(); foreach(var path in files)
{
BitmapImage image = new BitmapImage(); image.BeginInit(); image.UriSource = new System.Uri(path); image.EndInit(); image.Freeze(); models.Add(new ImageSourceModel() { ImageSource = image });
} lvImages.ItemsSource = models;
}
} public class ImageSourceModel
{
public ImageSource ImageSource { get; set; }
}

内存占用情况(此时只加载了20张图片,内存占用>1G):

优化方案:

1. 初始加载时,只加载部分图片并显示。当ScrollViewer滚动到底部时,再加载一部分。关于这个方案,可以参考 WPF MVVM模式下实现ListView下拉显示更多内容

但是这并不能解决最终内存占用过高的情况。

2. 给图片设置DecodePixelWidth属性,

    BitmapImage image = new BitmapImage();

    image.BeginInit();

    image.UriSource = new System.Uri(path);

    image.DecodePixelWidth = ;

    image.EndInit();

    image.Freeze();

    models.Add(new ImageSourceModel() { ImageSource = image });

此时的内存占用如图

内存降低的非常显著,此时同样多的图片内存占用只有40M左右。

最终我们可以把优化方案1和优化方案2结合起来。这样在加载多张图片时不会出现卡顿的现象。另外从用户体验的角度我们可以在图片显示出来前,先用一个Loading的动画效果过渡下。

感谢您的阅读。代码和测试图片请点击这里下载。

WPF中加载高分辨率图片性能优化的更多相关文章

  1. angular 图片加载失败 情况处理? 如何在ionic中加载本地图片 ?

    1.angular 图片加载失败 情况处理 在directive中定义组件,在ng-src错误时,调用err-src app.directive('errSrc',function(){ return ...

  2. [WebKit]浏览器的加载与页面性能优化

    非常棒.非常系统的一份资料,值得阅读! 原文来自百度泛用户体验. 作者:nwind 本文将探讨浏览器渲染的loading过程,主要有2个目的: 了解浏览器在loading过程中的实现细节,具体都做了什 ...

  3. DevExpress ChartControl大数据加载时有哪些性能优化方法

    DevExpress ChartControl加载大数据量数据时的性能优化方法有哪些? 关于图表优化,可从以下几个方面解决: 1.关闭不需要的可视化的元素(如LineMarkers, Labels等) ...

  4. 浅谈DevExpress<三>:在GridView中加载动态图片

    今天的演示效果如下:在GridView中的下拉框中选中一种颜色,则后面的加载相应的图片,如下图: 1.

  5. vue-router和webpack懒加载,页面性能优化篇

    在vue单页应用中,当项目不断完善丰富时,即使使用webpack打包,文件依然是非常大的,影响页面的加载.如果我们能把不同路由对应的组件分割成不同的代码块,当路由被访问时才加载对应的组件(也就是按需加 ...

  6. 【.net深呼吸】WPF异步加载大批量图像

    如何在WPF中加载大批量数据,并且不会阻塞UI线程,尤其是加载大量图片时,这活儿一直是很多朋友都相当关注的.世上没有最完美的解决之道,咱们但求相对较优的方案. 经过一些试验和对比,老周找到了一种算是不 ...

  7. 转:按需加载html 图片 css js

    按需加载是前端性能优化中的一项重要措施,按需加载是如何定义的呢?顾名思义,指的是当用户触发了动作时才加载对应的功能.触发的动作,是要看具体的业务场景而言,包括但不限于以下几个情况:鼠标点击.输入文字. ...

  8. android优化从网络中加载图片速度。。

    从网络中加载图片主要要注意两个方面的问题: 1.内存管理:图片占的内存很大,假如图片数量多,很容易让系统抛出out of memory的异常. 同时我们也要注意不同android版本中内存管理的区别. ...

  9. Android开发中如何解决加载大图片时内存溢出的问题

    Android开发中如何解决加载大图片时内存溢出的问题    在Android开发过程中,我们经常会遇到加载的图片过大导致内存溢出的问题,其实类似这样的问题已经屡见不鲜了,下面将一些好的解决方案分享给 ...

随机推荐

  1. Python类的特点 (2) :类属性与实例属性的关系

    测试代码: #encoding:utf-8 class Parent(object): x=1 #x是Parent类的属性(字段) ls=[1,2] #ls是一个列表,也是Parent类的属性(字段) ...

  2. python查找并删除相同文件-UNIQ File-wxPython版本

    今天用wxPython做了一个GUI程序,我称之为UNIQ File,实现查找指定目录内的相同文件,主要原理是计算文件的md5值(计算前先找出文件大小相同的文件,然后计算这些文件的md5值,而不是所有 ...

  3. Intellij Idea 14 生成serialVersionUID的方法

    默认情况下Intellij IDEA是关闭了继承了java.io.Serializable的类生成serialVersionUID的警告.如果需要ide提示生成serialVersionUID,那么需 ...

  4. rebot的使用

    rebot简要使用方法介绍 在介绍rebot前,首先说一下RobotFramework(后称RF)的主要输出文件.   当我们执行完一个RF脚本后,RF会输出3种文件.分别是Output.Log和Re ...

  5. hdu1520

    基本的树形dp #include <cstring> #include <cstdio> #include <vector> using namespace std ...

  6. Java使用for循环打印乘法口诀(正倒左右三角形)

    代码1: public void test1(){ for(int i = 1; i < 10 ; i ++){ for(int k = 1; k < i ; k ++){ System. ...

  7. ios 音乐播放,音乐信息显示方法

    下面的博客写的很清楚了 http://msching.github.io/blog/page/2/ 主要涉及AVAudioPlayer和下面这几个函数 MPNowPlayingInfoCenter.d ...

  8. springMVC配置文件位置及名称

    在web.xml文件内配置springMVC的DispatcherServlet的那个servlet内添加 <servlet> <servlet-name>mvc</se ...

  9. [第三方]SDWebImage获取网络图片控件的用法

    #import "UIImageView+WebCache.h" @interface WeatherViewController ()<UISearchBarDelegat ...

  10. nyoj739_笨蛋难题四

    笨蛋难题四 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 这些日子笨蛋一直研究股票,经过调研,终于发现xxx公司股票规律,更可喜的是 笨蛋推算出这家公司每天的股价, ...