【问题标题】:display an image retrieved from its URI显示从其 URI 检索到的图像
【发布时间】:2018-11-16 22:41:24
【问题描述】:

我在尝试序列化包含 BitmapSource 字段的对象时遇到了一些问题。

事实上,一开始,我有一个 ImageSource,但它似乎不可序列化。 所以我尝试使用关联的属性来存储一个字符串并将图像转换回字符串或从字符串转换回图像。但是现在没有显示图像:-(

这里是 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>

这是模型类中的 Image 属性和字段:

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 从 Internet 检索图像并存储它:

var myUri=new Uri(book0.LargeImage.URL);
bookToInsert.Image = new BitmapImage(myUri);

谢谢。

【问题讨论】:

  • 您确定要序列化字符串而不是字节数组吗?
  • 你知道的,我会使用我得到的第一个工作方法......一个字符串或一个字节数组等于我。顺便说一句,我发现很难获得一些关于如何序列化图像和位图编码器的教程......

标签: c# wpf image type-conversion bitmapimage


【解决方案1】:

当您从创建后立即关闭的流创建 BitmapSource 时,您必须设置 BitmapCacheOption.OnLoad。否则,流必须保持打开状态,直到实际使用 BitmapSource,例如显示在 Image 元素中。

public static BitmapSource Base64ToImage(string base64)
{
    using (var stream = new MemoryStream(Convert.FromBase64String(base64)))
    {
        return BitmapFrame.Create(
            stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
    }
}

几点说明:

  1. base64 编码和解码似乎没有必要。更好地序列化字节数组。
  2. 最初不要从 URL 创建 BitmapImage。最好通过网络请求直接获取图片缓冲区。
  3. 您不仅可以将 Image 元素的 Source 属性绑定到 ImageSource,还可以绑定到字符串、Uri 或字节数组。所以你的财产可能被声明为byte[] Image

尝试一个更简单的视图模型,如下所示:

public class ViewModel : INotifyPropertyChanged
{
    private byte[] image;

    public byte[] Image
    {
        get => image;
        set
        {
            image = value;
            OnPropertyChanged(nameof(Image));
        }
    }
}

并像这样设置 Image 属性:

var webClient = new WebClient();
viewModel.Image = webClient.DownloadData(book0.LargeImage.URL);

或异步:

var httpClient = new HttpClient();
viewModel.Image = await httpClient.GetByteArrayAsync(book0.LargeImage.URL);

【讨论】:

  • 不要创建初始BitmapImage,如编辑后的答案所示。
  • 你知道一本关于 .net 框架的参考书吗?我可以在其中深入了解这类信息?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-02
  • 2015-11-17
  • 1970-01-01
  • 2013-12-24
  • 2019-11-18
  • 2018-01-31
  • 2019-04-22
相关资源
最近更新 更多