UWP应用程序如何更快地加载图片?

4
我正在编写一款通用Windows平台应用程序,需要加载一些图片以在列表中显示。现在我的问题在于加载速度对用户来说太慢了。目前我使用绑定在XAML中设置图像的源文件,例如:{Binding Image}
我只能访问到全分辨率的图像,因此我想知道是否有一种方法可以在将它们放在UI上之前将这些图像变小,以便只需保留较小的图像在内存中。是否有一种方法可以配置Image UI元素以便它自行执行此调整大小的操作?
另外,是否有一种方法可以懒加载这些图像,因为现在我的UI被这些图像的加载所阻塞。
编辑:我使用以下代码将本地图像加载到我的Image中(这在ListView.ItemTemplate内部):
<Image
    Grid.Row="0"
    Source="{Binding Image}"
    Stretch="Uniform"
    VerticalAlignment="Center"/>

不确定这是否有帮助,但也许可以显示缩略图而不是整个图像? - Romasz
你从哪里获取这些图像?本地还是在线?阻塞发生在UI端还是加载这些图像只是需要很长时间。如果图像加载需要很长时间,也许这个链接可以帮助你:https://msdn.microsoft.com/zh-cn/windows/uwp/threading-async/asynchronous-programming-universal-windows-platform-apps - wuerzelchen
你是在创建BitmapImage还是绑定图像URL? - Archana
@wuerzelchen 我正在加载本地图像(从其他地方下载,但这部分在我填充包含本地图像URI的列表之前已经完成),这些本地图像很大(因为我需要它们高清的其他位置使用),但在列表中我只显示小图像。我使用相同的图像,这会导致UI被阻塞,因为加载这些大图像需要一定时间。我将编辑我的问题。 - vrwim
请发布代码,以便我们能够理解。 - Archana
显示剩余3条评论
2个回答

3
您可以使用转换器来懒加载和调整图像大小。以下是一个可用的转换器示例。使用此转换器,您可以轻松地进行懒加载。但是,我目前没有调整大小的示例。 转换器代码
class LoadAttachmentAsyncConverter : IValueConverter
{
    public override object Convert(object value, Type targetType, object parameter, string language)
    {
        Task<BitmapImage> taskToExecute = GetImage(<some parameter>);
        //Possibly handle some other business logic
        return new NotifyTaskCompletion<BitmapImage>(taskToExecute);
    }

    public async Task<BitmapImage> GetImage(object someParameter) {
        BitmapImage image = new BitmapImage();
        //do (async stuff) to fill the image;
        return image;
    }
}

XAML代码
<Image Source="{Binding Result}" DataContext="{Binding converterObjValue, Converter={StaticResource ConverterName}}"/>

要实现调整大小,您可以在此处找到信息:https://social.msdn.microsoft.com/Forums/en-US/490b9c01-db4b-434f-8aff-d5c495e67e55/how-to-crop-an-image-using-bitmaptransform?forum=winappswithcsharp


converterObjValue 在 XAML 中是什么?我可以把调整大小的代码放在“执行异步操作以填充图像”的部分,对吗? - vrwim
是的。它的功能是将数据上下文绑定到将返回的任务上。这样,源可以绑定到该任务的结果(加载的图像)。 - Tom Droste
谢谢!我会尝试这个,如果它解决了我的问题,我会接受的 :) - vrwim
好的,如果需要更多帮助,请告诉我。 - Tom Droste
@vrwim 如果我的解决方案解决了您的问题,请接受我的答案作为解决方案。 - Tom Droste
显示剩余4条评论

1

你也可以在你的虚拟机中进行延迟加载。

    // You can also use BitmapImage directly, if you'd like to make reloading faster and don't care memory usage.
    private WeakReference<BitmapImage> image;

    public BitmapImage Image
    {
        get
        {
            BitmapImage image;
            if(this.image != null && this.image.TryGetTarget(out image))
                return image;
            image = new BitmapImage();
            this.image = new WeakReference<BitmapImage>(image);
            var ignore = Task.Run(()=>
            {
                //Load image here.
                //Don't forget to use Dispatcher while calling SetSourceAsync() or setting Source.
            });
            return image;
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接