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

原文: 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:\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 = 800;

    image.EndInit();

    image.Freeze();

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

此时的内存占用如图

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

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

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

posted on 2018-11-12 14:33 NET未来之路 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/9946306.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值