WPF中加载高分辨率图片性能优化

来源:转载

在最近的项目中,遇到一个关于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:/Picsstring[] 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 = 800; image.EndInit(); image.Freeze(); models.Add(new ImageSourceModel() { ImageSource = image });

此时的内存占用如图

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

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

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


分享给朋友:
您可能感兴趣的文章:
随机阅读: