Silverlight读取Zip文件中的图片与视频
其实在我的 WebClient的使用文章中的例子就是如何使用WebClient读取zip文件中的资源,这篇文章是在其基础上增加了一些功能,从而构建出一个简单但较为完整的Demo。
首先看看Demo的截图:
下面我将一步步展示实现这个Demo的过程,这个需求就是读出Zip文件中的图片与视频。
Demo整体架构:
首先我们准备几张图片和视频,然后将其压缩至resource.zip文件中,做完之后,我们建立一个resource.xml文件记录压缩包内的资源
<?xml version="1.0" encoding="utf-8" ?><files><file type="video" name="a.wmv"/><file type="image" name="1.jpg"/><file type="image" name="2.jpg"/><file type="image" name="3.jpg"/><file type="image" name="4.jpg"/></files>
这个xml文件就记录了文件的类型和名称,完成之后我们将其压缩至resource.zip中(请注意:这一步对后面读取流会有影响)
现在我们将UI设计好
<Image x:Name="Image" /><MediaElement x:Name="Video" /><StackPanel HorizontalAlignment="Left" VerticalAlignment="Bottom" Opacity="0.5" Orientation="Horizontal" Margin="5,0,0,0" Name="stack"><Button Content="Prev" x:Name="PrevButton" Height="30" Margin="0,0,5,0" Width="80" Opacity="1" Cursor="Hand" IsEnabled="False" /><Button x:Name="NextButton" Height="30" Margin="0,0,5,0" Width="80" Opacity="1" Content="Next" Cursor="Hand" IsEnabled="False" /></StackPanel>
在UI上放置了一个Image和MediaElement控件来显示读取的资源
下面我们开始建立ResourceInfo.cs文件
public enum ResourceType{Video,Image}public class ResourceInfo{public ResourceType Type
{get; set;}public string Name{get; set;}}
文件的类型以枚举的形式表示,现在我们就在MainPage.xaml.cs中以WebClient完成数据的读取工作
先声明3个类成员变量:
private StreamResourceInfo zip;
private List<ResourceInfo> resourceInfo;
private int index = 0;
现在我们就先获取流,其完整代码:
public void Load(object sender,RoutedEventArgs e){Uri uri = new Uri(HtmlPage.Document.DocumentUri, "resource.zip");WebClient webClient = new WebClient();
webClient.OpenReadCompleted += (obj, args) =>{if (args.Error != null){return;
}// 这几步将读出的流信息封装到reader中,这样便于后面使用Linq To Xml操作
zip = new StreamResourceInfo(args.Result, null);StreamResourceInfo maininfo = Application.GetResourceStream(zip, new Uri("resource.xml", UriKind.Relative));StreamReader reader = new StreamReader(maininfo.Stream);
XDocument doc = XDocument.Load(reader);var file = from c in doc.Descendants("file")select new ResourceInfo
{Type = (ResourceType)Enum.Parse(typeof(ResourceType), c.Attribute("type").Value, true),Name = c.Attribute("name").Value
};resourceInfo = new List<ResourceInfo>();
resourceInfo.AddRange(file);this.PrevButton.IsEnabled = true;this.NextButton.IsEnabled = true;Display(resourceInfo[0]);};webClient.OpenReadAsync(uri);}public void Display(ResourceInfo resource){//获取相应的流数据
StreamResourceInfo media = Application.GetResourceStream(zip,new Uri(resource.Name,UriKind.Relative));
switch (resource.Type)
{case ResourceType.Image:
Image.Visibility = Visibility.Visible;Video.Visibility = Visibility.Collapsed;BitmapImage image = new BitmapImage();
image.SetSource(media.Stream);Image.Source = image;break;
case ResourceType.Video:
Image.Visibility = Visibility.Collapsed;Video.Visibility = Visibility.Visible;Video.SetSource(media.Stream);Video.Play();break;
}}
事实上加载这段代码后,我们已经可以将xml文件中标注的第一个资源a.wmv在页面进行成功的播放了
我们继续界面上的Button实现的循环显示上一条,下一条资源功能
private void StopVideo(){if (resourceInfo[index].Type == ResourceType.Video)
{Video.Stop();}}private void PrevButton_Click(object sender, RoutedEventArgs e){StopVideo();if (--index < 0)
{index = resourceInfo.Count - 1;}Display(resourceInfo[index]);}private void NextButton_Click(object sender, RoutedEventArgs e){StopVideo();if (++index >=resourceInfo.Count)
{index = 0;}Display(resourceInfo[index]);}
如此我们就完成了这个Demo