[英]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内部,我们可以通过将EnableLazyLoading
和IsCacheEnabled
属性设置为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.