WinRT 将图像绑定到字符串或存储文件

WinRT binding an Image to a string or StorageFile

在 select 从 FilePicker 中编辑图像后,我试图显示来自 StorageFile 的图像。由于 ImageSource 必须是 URIImageSource,我试图从 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;
}

但是,它 returns 是 Task<Image>,它也不是 ImageSourceURI。看起来它应该比我想做的更直接,但我只是没有看到它。另外,我尝试只在 XAML 中为 Image.Source 指定一个文件,它工作正常。我只是无法根据来自 FilePicker.

的 selected 文件来 link 它

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

编辑:

我能够使用下面我 post 编辑的解决方案完成此任务。非常感谢 Jerry Nixon 的博客 post:http://blog.jerrynixon.com/2014/11/reading-and-writing-base64-in-windows.html

最好的解决方案是在后面的代码中设置源而不是使用绑定,因为它可以让您处理诸如取消之类的事情,以防 ImagePath 在上一个图像仍在加载时更新。

或者,您可以创建一个位图,启动加载它的任务,然后 return 在该任务完成之前,例如

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);
    }
}

如果其他人在寻找答案时遇到这个问题,我最终针对我的情况所做的是,采用从 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 encoding/decoding 我在伟大的 Jerry Nixon 的博客上找到了这里:http://blog.jerrynixon.com/2014/11/reading-and-writing-base64-in-windows.html