第十三章:位图(六)

流式位图

如果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="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             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对象,它是ImageSource.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属性。
201808202111050391
看起来好像你可以通过使用更多地控制图像的下载WebRequest和ImageSource.FromStream比用ImageSource.FromUri,但是ImageSource.FromUri方法有一个很大的优势:它将下载的位图缓存在应用程序专用的存储区域中。 正如您所见,您可以关闭缓存,但如果您使用Image?Source.FromStream而不是ImageSource.FromUri,您可能会发现需要缓存图像,这将是一个更大的工作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值