微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Silverlight图片资源引用及动态下载

1 图片直接编译到silverlight应用程序的dll当中

这也是缺省的方法,具体做法是:在visual studio中,选择一个图片,查看属性窗口。
Build Action: Resource (注意不要选择Embeded Resource,Silverlight无法识别该格式。)
copy to output directory: Do not copy
于是在Xaml中可以这样引用图片
<Image Source="Images/grandpiano.jpg"></Image>
用C#引用:
img.source = new BitmapImage(new Uri("Images/grandpiano.jpg",UriKind.Relative));
注意BitmapImage对象有个 ImageOpened事件,可以用来通知图片已经可用。
或者:
img.source = new BitmapImage(new Uri("/SilverlightApplication1;component/Images/grandpiano.jpg",UriKind.Relative));
我们还可以选择另外一个相对复杂一些的方法
StreamResourceInfo sr = Application.GetResourceStream(new Uri("/SilverlightApplication1;component/Images/grandpiano.jpg",UriKind.Relative));
BitmapImage bmp = new BitmapImage();
bmp.SetSource(sr.Stream);
img.source = bmp;
注意下面的用法错误的:
StreamResourceInfo sr = Application.GetResourceStream(new Uri("Images/grandpiano.jpg",UriKind.Relative));
BitmapImage bmp = new BitmapImage();
bmp.SetSource(sr.Stream);
img.source = bmp;
运行时会显示错误信息。

2 把图片资源放到silverlight应用程序的主包(Xap)中

具体做法是:在visual studio中,选择一个图片,查看属性窗口。
Build Action: Content
copy to output directory: Always copy
这时候把xap文件改名为zip文件,可以发现Images目录下有grandpiano.jpg文件。说明图片在xap包中,但是没有编译到dll中。
在Xaml中可以这样引用图片
Image Source="/Images/grandpiano.jpg"></Image>
注意跟前面的区别:最前面的“/”代表xap文件的根路径。
用C#引用:
img.source = new BitmapImage(new Uri("Images/grandpiano.jpg"));
或者:
StreamResourceInfo sr = Application.GetResourceStream(new Uri("Images/grandpiano.jpg",UriKind.Relative));
BitmapImage bmp = new BitmapImage();
bmp.SetSource(sr.Stream);
img.source = bmp;
注意在C#引用中没有最前面的“/”。
总的来说,把文件放到主包中与编译到dll中比较相像。但都不是动态下载,因为图片都还在主包中,会跟主程序一同下载。

3 把图片放到web服务器上

为方便描述起见,假设图片与silverlight应用程序在同一个域,不存在跨域的问题。为了突出主题,跨域访问的授权许可这里就不讨论了。另外假设图片目录与silverlight主包在同一个目录。即
/ClientBin/
App.Xap
Images/
具体做法是:在visual studio中,选择一个图片,查看属性窗口。
build action: None
copy to output directory: Always copy
在Xaml中可以这样引用图片
<Image Source="/Images/grandpiano.jpg"></Image>
用C#引用:
img.source = new BitmapImage(new Uri("Images/grandpiano.jpg"));
咦,发现没有?这与方法2完全相同!没错,Silverlight会首先检查xap包,如果没有找到图片,会再检查web服务器。也就是说,相同的代码,你可以在方法2和方法3中自由选择和切换,方便吧?
方法3虽然与方法2代码相同,本质上已经根本不同。方法3中图片文件已经不在xap文件中,而是在web服务器上,意味着xap文件的尺寸已经大大减小,silverlight应用程序的加载时间大大缩小。缺点是这些图片因为会在引用时动态从服务器下载,直到下载完成才可使用,所以会导致延迟。不过由于Silverlight缓存资源的缘故,只有第一次引用会有延迟,再次引用时将直接从缓存中读取文件,没有丝毫延迟。
除此之外,更加灵活和强大的方式是使用上节介绍的WebClient类的OpenReadAsync方法代码如下:
 	string uri = Application.Current.Host.source.AbsoluteUri;
        int index = uri.IndexOf("/ClientBin");
        uri = uri.Substring(0,index) + "/Images/grandpiano.jpg";
        // Begin the download.
        WebClient webClient = new WebClient();
        webClient.OpenReadCompleted += webClient_OpenReadCompleted;
        webClient.OpenReadAsync(new Uri(uri));

	private void webClient_OpenReadCompleted(object sender,OpenReadCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                // (Add code to display error or degrade gracefully.)
            }
            else
            {
                BitmapImage bitmapImage = new BitmapImage();
                bitmapImage.SetSource(e.Result);
                img.source = bitmapImage;
            }
        }
webClient与浏览器共享缓存,即webClient会把下载的文件保存到浏览器缓存目录中,如果文件已经被缓存,再次调用OpenReadAsync方法时将直接中缓存中获得文件,这将大大减小获取文件的时间。但是从浏览器缓存获取文件仍然会有一点点延迟,通常不会被察觉,但是如果用于显示动画,这个延迟会导致严重闪烁。解决这个问题的办法就是把下载的资源保存到silverlight的内存中,引用时直接从内存读取。Application.Resources是个不错的选择,可以用于资源缓存。

4. 把图片打包放到web服务器上

图片打包放置到web服务器上更便于图片资源的管理和维护,而且可以把图片分类保存到不同的压缩包里。因为下载图片时通常是同类图片一起下载,下载一个包当然比分开下载许多图片方便快捷许多。
具体方法是把图片打包(zip)后,放置到ClientBin目录。然后代码如下:
void DownloadImagePart(string imgPart)
        {
            WebClient wc = new WebClient();
            wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);
            wc.OpenReadAsync(new Uri("imgs.zip",UriKind.Relative),imgPart);
        }

        void wc_OpenReadCompleted(object sender,OpenReadCompletedEventArgs e)
        {
            StreamResourceInfo sri = new StreamResourceInfo(e.Result as Stream,null);
            String sURI = e.UserState as String;
            StreamResourceInfo imagestream = Application.GetResourceStream(sri,new Uri(sURI,UriKind.Relative));
            BitmapSource imgsrc = new BitmapSource();
            imgsrc.SetSource(imagestream.Stream);
            ImgToFill.source = imgsrc;
        }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐