繁体   English   中英

在 WinRT/UWP 中加载远程认证图像

[英]Load Remote Authenticated Image in WinRT/UWP

我正在尝试在 XAML 中加载远程图像,该图像需要身份验证标头才能成功下载。

目前我正在使用我自己的缓存服务,我使用 HttpClient 下载图像并将文件存储到磁盘。 在后续加载时,我只是将图像绑定到缓存文件的绝对文件路径,如下所示:

              <Image Width="50"
                   Height="50"
                   Stretch="UniformToFill"
                   HorizontalAlignment="Center"
                   VerticalAlignment="Center"
                   Source="{Binding CachedImagePath}"/>

这有效,但是我对从文件加载图像所需的时间不太满意。 这似乎比我使用 XAML 缓存慢得多。

所以我的问题是:

1) 当我将图像绑定到远程 URI 时,有没有办法传递身份验证标头?

2)如果没有,您能否推荐一种比我目前拥有的更快的从磁盘加载图像的方法?

Windows Community Toolkit包含一个ImageEx控件,可用于管理远程图像的本地缓存和 UI 中图像的异步加载。

作为他们如何实现图像下载的副作用,我们可以访问它使用的静态HttpClient实例,并使用身份验证或您的 API 可能需要的其他标头设置DefaultRequestHeaders

如果您的所有图像都来自同一个经过身份验证的服务器,则此解决方案有效,该工具包是开源的,因此您可以下载源代码并根据自己的需要更改实现。

默认情况下, ImageEx控件管理 Visible 状态,同时图像正在加载一个漂亮的淡入动画,但是您可以覆盖它,甚至提供一个PlaceHolder图像或文本。

  • 一种高级方案是使用PlaceHolder首先渲染可能被主动缓存的图像的低分辨率版本。 这超出了本文的范围,但强调了此解决方案的可扩展性。

魔法发生在这个控件使用的ImageCache内部,我们可以通过将EnableLazyLoadingIsCacheEnabled属性设置为True来强制使用 ImageCache,只要我们在加载图像之前设置请求标头,我们就可以直接绑定Source到外部 URL 以访问文件。

xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
<controls.ImageEx Width="50"
                  Height="50"
                  Stretch="UniformToFill"
                  HorizontalAlignment="Center"
                  VerticalAlignment="Center"

                  EnableLazyLoading="True"
                  IsCacheEnabled="True"
                  Source="{Binding ImageUrl}" />

这种行为没有明确记录,通过使用反射访问内部HttpClient我们接受存在这可能在未来版本中不起作用的风险。

理想情况下,因为 ImageCache.Instance 是一个静态成员,我们只需要在用户登录时设置 Auth 标头,以下代码展示了如何使用任意标头执行此操作:

// set the auth header on the Image Cache!
var httpClient = ImageCache.Instance
                           .GetType()
                           .GetProperty("HttpClient", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.GetProperty | System.Reflection.BindingFlags.NonPublic)
                           .GetValue(ImageCache.Instance)
                           as System.Net.Http.HttpClient;
        Runtime.ConfigureHttpClient(httpClient);

httpClient.DefaultRequestHeaders.Authorization = 
    new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "---MyUserAuthToken---");
httpClient.DefaultRequestHeaders.Add("My-Token", "---arbitrary token---");

运行时性能很好,但是你可以配置ImageCache来在内存中保留一些图像,或者我们可以显式或预先加载图像:

在下文中,假设item是一个数据对象,它具有一个ImageUrl ,其中包含一个指向需要身份验证的资源的 URL。

// Define max memory cache size
ImageCache.Instance.MaxMemoryCacheCount = 200;

// Precache data and save it in memory
await ImageCache.Instance.PreCacheAsync(new Uri(item.ImageUrl), Path.GetFileName(item.Thumbnail), true);

// Precache data and save it in on local hard drive
await ImageCache.Instance.PreCacheAsync(new Uri(item.ImageUrl), Path.GetFileName(item.Thumbnail), false);

// Clear cache
await ImageCache.Instance.ClearAsync();

这可以通过实现IWeRequestCreate来实现。 您可能需要通过添加已实现接口的类详细信息来更改 app.config 文件。

因此,每当创建 webrequest 时,它都会通过这个自定义实现,并且您可以在那里传递身份验证标头,因为HttpWeRequest包含一个属性Header

有关更多详细信息,请查看此帖子

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM