2015-01-21 54 views
0

我试图从FilePicker中选择一个StorageFile后显示图像。由于ImageSource必须是URIImageSource,因此我试图从StorageFile中获取其中的任一个。WinRT将图像绑定到字符串或StorageFile

我很难获取数据绑定在XAML中的Image上工作。我曾尝试以下:

<Image Width="300" 
     Height="300" 
     x:Name="LogoImage"> 
    <Image.Source> 
     <BitmapImage UriSource="{Binding ImagePath}" /> 
    </Image.Source> 
</Image> 

这样是不行的,作为StorageFilePath属性不是URI。另外,我不能直接绑定到StorageFile本身,因为它不是ImageSource

我试图用这个方法:

public async Task<Image> GetImageAsync(StorageFile storageFile) 
{ 
    BitmapImage bitmapImage = new BitmapImage(); 
    FileRandomAccessStream stream = (FileRandomAccessStream)await storageFile.OpenAsync(FileAccessMode.Read); 
    bitmapImage.SetSource(stream); 
    Image image = new Image(); 
    image.Source = bitmapImage; 
    return image; 
} 

但是,它返回一个Task<Image>,这也不是一个ImageSourceURI。它似乎应该比我想要做的更直接,但我只是没有看到它。另外,我试过在XAML中为Image.Source指定一个文件,它工作正常。我只是无法根据FilePicker中选定的文件进行链接。

我的最终目标是:从FilePicker中选择一个文件,更新显示的ImageImageSource,编码为base64以存储在数据库中。然后,从数据库加载现有的base64字符串,转换回Image进行显示。

编辑:

我能够完成我使用下面张贴的解决了这个任务。非常感谢杰里·尼克松的博客文章:http://blog.jerrynixon.com/2014/11/reading-and-writing-base64-in-windows.html

回答

0

如果任何人遇到了这个问题寻找一个答案,我最终落得这样做对我的情况,是采取从FilePicker选择StorageFile,编码为Base64字符串(我将保存到我的数据库供以后检索)。

一旦我有base64字符串,我可以将该字符串解码为ImageSource以在代码隐藏中设置。这里是我的全ButtonClick事件处理程序:

private async void ChooseImage_Click(object sender, RoutedEventArgs e) 
{ 
    var filePicker = new FileOpenPicker(); 
    filePicker.FileTypeFilter.Add(".jpg"); 
    filePicker.ViewMode = PickerViewMode.Thumbnail; 
    filePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary; 
    filePicker.SettingsIdentifier = "picker1"; 
    filePicker.CommitButtonText = "Open File to Process"; 

    var files = await filePicker.PickMultipleFilesAsync(); 

    if (files.Count > 0) 
    { 
     // encode the storage file to base64 
     var base64 = await Encoding.ToBase64(files[0]); 

     // asynchronously save base64 string to database 
     // ... 

     // decode the base64 and set the image source 
     LogoImage.Source = await Encoding.FromBase64(base64); 
    } 
} 

的base64编码/解码,我发现在伟大的杰里尼克松的博客在这里:http://blog.jerrynixon.com/2014/11/reading-and-writing-base64-in-windows.html

+0

这对内存和CPU使用来说都很糟糕... – ManIkWeet 2016-09-17 22:46:22

+0

我同意。我肯定会赞赏一些更有效的方式来实现这一目标的反馈。 – 2016-09-19 01:13:35

+0

我还没有找到答案,可悲的是... – ManIkWeet 2016-09-19 06:36:49

2

最好的解决方案是将代码源设置在后面而不是使用绑定,因为它可以让你处理类似取消的情况,以防ImagePath在更新时图像仍在加载。

或者,您可以创建一个位图,启动加载它的任务并在任务完成之前返回,例如,

public Image GetImage(StorageFile storageFile) 
{ 
    var bitmapImage = new BitmapImage(); 
    GetImageAsync(bitmapImage, storageFile); 

    // Create an image or return a bitmap that's started loading 
    var image = new Image(); 
    image.Source = bitmapImage; 

    return image ; 
} 

private async Task GetImageAsync(BitmapImage bitmapImage, StorageFile storageFile) 
{ 
    using (var stream = (FileRandomAccessStream)await storageFile.OpenAsync(FileAccessMode.Read)) 
    { 
     await bitmapImage.SetSource(stream); 
    } 
} 
+0

优秀,我会尝试今晚。我将显示'FilePicker'并将代码源设置为我的应用程序的详细信息页面,但在父页面中,我仍然希望能够使用“GridView”的绑定。 我想我可以在代码隐藏中通过在OnNavigatedTo事件中设置源代码来实现。 – 2015-01-21 18:57:35

+0

感谢您的回答。我最终为了自己的目的走了一条不同的路线。无论如何,我需要将我的图像编码为base64,以便将字符串属性保存到数据库中。我在下面发布我的解决方案 – 2015-01-22 06:22:50