WinRT 将图像绑定到字符串或存储文件
WinRT binding an Image to a string or StorageFile
在 select 从 FilePicker
中编辑图像后,我试图显示来自 StorageFile
的图像。由于 Image
的 Source
必须是 URI
或 ImageSource
,我试图从 StorageFile
.
我很难让数据绑定在 XAML 中的 Image
上工作。我尝试了以下方法:
<Image Width="300"
Height="300"
x:Name="LogoImage">
<Image.Source>
<BitmapImage UriSource="{Binding ImagePath}" />
</Image.Source>
</Image>
这种方式行不通,因为 StorageFile
的 Path
属性 不是 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>
,它也不是 ImageSource
或 URI
。看起来它应该比我想做的更直接,但我只是没有看到它。另外,我尝试只在 XAML 中为 Image.Source
指定一个文件,它工作正常。我只是无法根据来自 FilePicker
.
的 selected 文件来 link 它
我的最终目标是:select 来自 FilePicker
的文件,更新显示的 Image
的 ImageSource
,编码为 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
在 select 从 FilePicker
中编辑图像后,我试图显示来自 StorageFile
的图像。由于 Image
的 Source
必须是 URI
或 ImageSource
,我试图从 StorageFile
.
我很难让数据绑定在 XAML 中的 Image
上工作。我尝试了以下方法:
<Image Width="300"
Height="300"
x:Name="LogoImage">
<Image.Source>
<BitmapImage UriSource="{Binding ImagePath}" />
</Image.Source>
</Image>
这种方式行不通,因为 StorageFile
的 Path
属性 不是 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>
,它也不是 ImageSource
或 URI
。看起来它应该比我想做的更直接,但我只是没有看到它。另外,我尝试只在 XAML 中为 Image.Source
指定一个文件,它工作正常。我只是无法根据来自 FilePicker
.
我的最终目标是:select 来自 FilePicker
的文件,更新显示的 Image
的 ImageSource
,编码为 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