流式位图
如果ImageSource类没有FromUri或FromResource方法,您仍然可以通过Web访问位图或作为PCL中的资源存储。 您可以使用ImageSource.FromStream或StreamImageSource类执行这两个作业以及其他几个作业。
ImageSource.FromStream方法比StreamImageSource更容易使用,但两者都有点奇怪。 ImageSource.FromStream的参数不是Stream对象,而是返回Stream对象的Func对象(不带参数的方法)。 Stream?ImageSource的Stream属性同样不是Stream对象,而是具有CancellationToken参数并返回Task 对象的Func对象。
访问流
BitmapStreams程序包含一个XAML文件,其中有两个Image元素等待位图,每个Image元素都使用ImageSource.FromStream在代码隐藏文件中设置:
-
<ContentPage xmlns=""
-
xmlns:x=""
-
x:Class="BitmapStreams.BitmapStreamsPage">
-
<StackLayout>
-
<Image x:Name="image1"
-
HorizontalOptions="Center"
-
VerticalOptions="CenterAndExpand" />
-
<Image x:Name="image2"
-
HorizontalOptions="Center"
-
VerticalOptions="CenterAndExpand" />
-
</StackLayout>
-
</ContentPage>
第一个Image是从PCL中的嵌入资源设置的; 第二个是通过Web访问的位图设置的。
在第4章“滚动堆栈”中的BlackCat程序中,您了解了如何在PCL中为使用EmbeddedResource的Build Action存储的任何资源获取Stream对象。 您可以使用相同的技术来访问存储为嵌入资源的位图:
-
public partial class BitmapStreamsPage : ContentPage
-
{
-
public BitmapStreamsPage()
-
{
-
InitializeComponent();
-
// Load embedded resource bitmap.
-
string resourceID = "BitmapStreams.Images.IMG_0722_512.jpg";
-
image1.Source = ImageSource.FromStream(() =>
-
{
-
Assembly assembly = GetType().GetTypeInfo().Assembly;
-
Stream stream = assembly.GetManifestResourceStream(resourceID);
-
return stream;
-
});
-
…
-
}
-
}
ImageSource.FromStream的参数定义为返回Stream对象的函数,因此该参数在此处表示为lambda函数。 对GetType方法的调用返回BitmapStreamsPage类的类型,GetTypeInfo提供有关该类型的更多信息,包括包含该类型的Assembly对象。 那就是BitmapStream PCL程序集,它是具有嵌入式资源的程序集。 GetManifestResourceStream返回一个Stream对象,它是mageSource.FromStream想要的返回值。
如果您需要对这些资源的名称提供一点帮助,GetManifestResourceNames将返回一个字符串对象数组,其中包含PCL中的所有资源ID。 如果您无法弄清楚GetManifestResourceStream无法正常工作的原因,请首先检查以确保您的资源具有EmbeddedResource的Build Action,然后调用GetManifestResourceNames以获取所有资源ID。
要通过Web下载位图,可以使用之前在ImageBrowser程序中演示的相同WebRequest方法。 在这个程序中,BeginGetResponse回调是一个lambda函数:
-
public partial class BitmapStreamsPage : ContentPage
-
{
-
public BitmapStreamsPage()
-
{
-
…
-
// Load web bitmap.
-
Uri uri = new Uri("https://developer.xamarin.com/demo/IMG_0925.JPG?width=512");
-
WebRequest request = WebRequest.Create (uri);
-
request.BeginGetResponse((IAsyncResult arg) =>
-
{
-
Stream stream = request.EndGetResponse(arg).GetResponseStream();
-
if (Device.OS == TargetPlatform.WinPhone ||
-
Device.OS == TargetPlatform.Windows)
-
{
-
MemoryStream memStream = new MemoryStream();
-
stream.CopyTo(memStream);
-
memStream.Seek(0, SeekOrigin.Begin);
-
stream = memStream;
-
}
-
ImageSource imageSource = ImageSource.FromStream(() => stream);
-
Device.BeginInvokeOnMainThread(() => image2.Source = imageSource);
-
}, null);
-
}
-
}
BeginGetResponse回调还包含两个嵌入的lambda函数! 回调的第一行获取位图的Stream对象。 此Stream对象不太适合Windows运行时,因此内容将复制到MemoryStream。
下一个语句使用short lambda函数作为ImageSource.FromStream的参数来定义返回该流的函数。 BeginGetResponse回调的最后一行是对Device.BeginInvokeOnMainThread的调用,以将ImageSource对象设置为Image的Source属性。
看起来好像你可以通过使用更多地控制图像的下载WebRequest和ImageSource.FromStream比用ImageSource.FromUri,但是ImageSource.FromUri方法有一个很大的优势:它将下载的位图缓存在应用程序专用的存储区域中。 正如您所见,您可以关闭缓存,但如果您使用Image?Source.FromStream而不是ImageSource.FromUri,您可能会发现需要缓存图像,这将是一个更大的工作。
阅读(5437) | 评论(0) | 转发(0) |