Windows store app[Part 2]:全新的File System与Uri不匹配的问题
在Win 8 App的安全沙箱内,除了使用文件选取器FileOpenPicker外,没有其他办法调用某个盘符的数据。
全新的Storage命名空间,借鉴了IOS与Android的设计。
下面引用一个图片绑定的简单例子:
原来WPF我们可以这样写:
1 <Grid Background="Red"> 2 <Image x:Name="bg1" Source="ms-appx:///Assets/shanghai.jpg"></Image> 3 </Grid>
也可以在Code-Behind这样写:
this.DataContext = new BitmapImage(new Uri("ms-appx:///Assets/shanghai.jpg"));
XAML:
<Image x:Name="bg1" Source="{Binding}"></Image>
效果都是这样:
下面我们用Win8 App的Storage来重写一下上面的代码。
为了举例,我们需要引用本地图片库的图片文件。
在AppPackage.appxmanifest中,加上配置
1 <Capabilities> 2 <Capability Name="picturesLibrary" /> 3 </Capabilities>
Code-Behind:
1 var file = KnownFolders.PicturesLibrary.GetFileAsync("shanghai.jpg").AsTask().Result; 2 3 this.DataContext = new BitmapImage(new Uri(file.Path));
运行程序,图片并没有显示,这说明Storage是不支持Uri的。
解决方案1:通过读取File的Stream,Set Image的Source,代码如下:
1 var file = await KnownFolders.PicturesLibrary.GetFileAsync("shanghai.jpg"); 2 using (var fileStream = await file.OpenAsync(FileAccessMode.Read)) { 3 BitmapImage image = new BitmapImage(); 4 image.SetSource(fileStream); 5 this.DataContext = image; 6 }
解决方案2:通过WriteBitmap类实现,代码如下:
1 async private void GetImage() { 2 var file = await KnownFolders.PicturesLibrary.GetFileAsync("shanghai.jpg"); 3 using (var stream = await file.OpenAsync(FileAccessMode.Read)) { 4 BitmapImage image = new BitmapImage(); 5 image.SetSource(stream); 6 stream.Seek(0); 7 backgroundBmp = new WriteableBitmap(image.PixelWidth, image.PixelHeight); 8 await backgroundBmp.SetSourceAsync(stream); 9 this.DataContext = backgroundBmp; 10 } 11 } 12 13 private WriteableBitmap backgroundBmp;
同样,也可以通过引用WriteableBitmapEx.WinRT简化写法,代码如下:
1 async private void GetImage() { 2 var file = await KnownFolders.PicturesLibrary.GetFileAsync("shanghai.jpg"); 3 using (var stream = await file.OpenAsync(FileAccessMode.Read)) { 4 BitmapImage image = new BitmapImage(); 5 image.SetSource(stream); 6 stream.Seek(0); 7 backgroundBmp = await BitmapFactory.New(image.PixelWidth, image.PixelHeight).FromStream(stream); 8 this.DataContext = backgroundBmp; 9 } 10 } 11 12 private WriteableBitmap backgroundBmp;
解放方案1和2的区别,WriteableBitmap可以精确指定生成的Image的区域,这样就可以通过WriteableBitmap实现图片的缩放,裁剪。
代码:戳