显示从其 URI 检索到的图像
display an image retrieved from its URI
我在尝试序列化包含 BitmapSource 字段的对象时遇到一些问题。
其实一开始我有一个ImageSource但是好像不能序列化。
所以我尝试使用关联的 属性 来存储字符串并转换和转换回图像 to/from string.but 现在没有图像显示:-(
这里是 XAML 图片标签:
<Image
x:Name="bookCover"
Grid.Row="0"
Grid.RowSpan="1"
Grid.Column="0"
MaxWidth="200"
MaxHeight="320"
Margin="5"
Source="{Binding Image}" SizeChanged="bookCover_SizeChanged" >
</Image>
这是模型中的图像 属性 & 字段 class:
public string _image;
public BitmapSource Image
{
get => Base64ToImage(_image);
set
{
_image =ImageToBase64(value);
OnPropertyChanged("Image");
}
}
及其相关方法:
public static string ImageToBase64(BitmapSource bitmap)
{
var encoder = new JpegBitmapEncoder();
var frame = BitmapFrame.Create(bitmap);
encoder.Frames.Add(frame);
using (var stream = new MemoryStream())
{
encoder.Save(stream);
return Convert.ToBase64String(stream.ToArray());
}
}
public static BitmapSource Base64ToImage(string base64)
{
byte[] bytes = Convert.FromBase64String(base64);
using (var stream = new MemoryStream(bytes))
{
return BitmapFrame.Create(stream);
}
}
这里我的程序通过其 URI 从互联网上检索图像并存储它:
var myUri=new Uri(book0.LargeImage.URL);
bookToInsert.Image = new BitmapImage(myUri);
谢谢。
从创建后立即关闭的流创建 BitmapSource 时,必须设置 BitmapCacheOption.OnLoad
。否则,流必须保持打开状态,直到实际使用 BitmapSource,例如显示在图像元素中。
public static BitmapSource Base64ToImage(string base64)
{
using (var stream = new MemoryStream(Convert.FromBase64String(base64)))
{
return BitmapFrame.Create(
stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}
}
一些注意事项:
- base64编码解码好像没必要。更好地序列化一个字节数组。
- 最初不要从 URL 创建 BitmapImage。最好直接通过网络请求获取图像缓冲区。
- 您不仅可以将 Image 元素的 Source 属性 绑定到 ImageSource,还可以绑定到字符串、Uri 或字节数组。所以你的 属性 可能被声明为
byte[] Image
.
尝试像这样更简单的视图模型:
public class ViewModel : INotifyPropertyChanged
{
private byte[] image;
public byte[] Image
{
get => image;
set
{
image = value;
OnPropertyChanged(nameof(Image));
}
}
}
并像这样设置图像 属性:
var webClient = new WebClient();
viewModel.Image = webClient.DownloadData(book0.LargeImage.URL);
或异步:
var httpClient = new HttpClient();
viewModel.Image = await httpClient.GetByteArrayAsync(book0.LargeImage.URL);
我在尝试序列化包含 BitmapSource 字段的对象时遇到一些问题。
其实一开始我有一个ImageSource但是好像不能序列化。 所以我尝试使用关联的 属性 来存储字符串并转换和转换回图像 to/from string.but 现在没有图像显示:-(
这里是 XAML 图片标签:
<Image
x:Name="bookCover"
Grid.Row="0"
Grid.RowSpan="1"
Grid.Column="0"
MaxWidth="200"
MaxHeight="320"
Margin="5"
Source="{Binding Image}" SizeChanged="bookCover_SizeChanged" >
</Image>
这是模型中的图像 属性 & 字段 class:
public string _image;
public BitmapSource Image
{
get => Base64ToImage(_image);
set
{
_image =ImageToBase64(value);
OnPropertyChanged("Image");
}
}
及其相关方法:
public static string ImageToBase64(BitmapSource bitmap)
{
var encoder = new JpegBitmapEncoder();
var frame = BitmapFrame.Create(bitmap);
encoder.Frames.Add(frame);
using (var stream = new MemoryStream())
{
encoder.Save(stream);
return Convert.ToBase64String(stream.ToArray());
}
}
public static BitmapSource Base64ToImage(string base64)
{
byte[] bytes = Convert.FromBase64String(base64);
using (var stream = new MemoryStream(bytes))
{
return BitmapFrame.Create(stream);
}
}
这里我的程序通过其 URI 从互联网上检索图像并存储它:
var myUri=new Uri(book0.LargeImage.URL);
bookToInsert.Image = new BitmapImage(myUri);
谢谢。
从创建后立即关闭的流创建 BitmapSource 时,必须设置 BitmapCacheOption.OnLoad
。否则,流必须保持打开状态,直到实际使用 BitmapSource,例如显示在图像元素中。
public static BitmapSource Base64ToImage(string base64)
{
using (var stream = new MemoryStream(Convert.FromBase64String(base64)))
{
return BitmapFrame.Create(
stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}
}
一些注意事项:
- base64编码解码好像没必要。更好地序列化一个字节数组。
- 最初不要从 URL 创建 BitmapImage。最好直接通过网络请求获取图像缓冲区。
- 您不仅可以将 Image 元素的 Source 属性 绑定到 ImageSource,还可以绑定到字符串、Uri 或字节数组。所以你的 属性 可能被声明为
byte[] Image
.
尝试像这样更简单的视图模型:
public class ViewModel : INotifyPropertyChanged
{
private byte[] image;
public byte[] Image
{
get => image;
set
{
image = value;
OnPropertyChanged(nameof(Image));
}
}
}
并像这样设置图像 属性:
var webClient = new WebClient();
viewModel.Image = webClient.DownloadData(book0.LargeImage.URL);
或异步:
var httpClient = new HttpClient();
viewModel.Image = await httpClient.GetByteArrayAsync(book0.LargeImage.URL);