来自MemoryStream的UWP BitmapImage SetSource挂起

时间:2016-05-23 06:46:10

标签: c# binding uwp bitmapimage

在我的UWP应用程序中,我将图像以byte []的形式存储在SQLite数据库中。然后当我从db中检索我的对象时,我将它们绑定到具有Image控件的GridView数据模板。由于我无法将Image的Source直接绑定到数组,所以我在我的对象类中创建了一个BitmapImage属性来将Image控件绑定到:

    public BitmapImage Icon
    {
        get
        {
            using (var stream = new MemoryStream(icon))
            {
                stream.Seek(0, SeekOrigin.Begin);
                var img = new BitmapImage();
                img.SetSource(stream.AsRandomAccessStream());
                return img;
            }
        }
    }

问题是,我的应用程序挂在img.SetSource行上。 经过一些实验,我发现第二个MemoryStream可以解决这个问题:

    public BitmapImage Icon
    {
        get
        {
            using (var stream = new MemoryStream(icon))
            {
                stream.Seek(0, SeekOrigin.Begin);
                var s2 = new MemoryStream();
                stream.CopyTo(s2);
                s2.Position = 0;
                var img = new BitmapImage();
                img.SetSource(s2.AsRandomAccessStream());
                s2.Dispose();
                return img;
            }
        }
    }

由于某种原因,它可以工作,不会挂起。我想知道为什么?以及如何妥善处理这种情况?谢谢!

4 个答案:

答案 0 :(得分:4)

我建议您在应用程序中显示图像之前使用IValueConverter界面。

class ImageConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        if (value == null || !(value is byte[]))
            return null;
        using (InMemoryRandomAccessStream ms = new InMemoryRandomAccessStream())
        {
            using (DataWriter writer = new DataWriter(ms.GetOutputStreamAt(0)))
            {
                writer.WriteBytes((byte[])value);
                writer.StoreAsync().GetResults();
            }
            var image = new BitmapImage();
            image.SetSource(ms);
            return image;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

答案 1 :(得分:0)

为什么不使用Base64?在sqlite数据库列中保存Base64 Image并轻松将其绑定到Image控件。

<Image Source="{Binding Path=imagedata}" Height="120"  Width="120"></Image>

从sqlite db中绑定Gridview中的图像要容易得多。

答案 2 :(得分:0)

我使用了转换器中使用的扩展方法:

    public static BitmapImage AsBitmapImage(this byte[] byteArray)
    {
        if (byteArray != null)
        {
            using (var stream = new InMemoryRandomAccessStream())
            {
                stream.WriteAsync(byteArray.AsBuffer()).GetResults(); 
                          // I made this one synchronous on the UI thread;
                          // this is not a best practice.
                var image = new BitmapImage();
                stream.Seek(0);
                image.SetSource(stream);
                return image;
            }
        }

        return null;
    }

答案 3 :(得分:0)

在发现从RandomAccessStreams加载的图像时,我一直遇到问题。它们在应用程序中的视觉效果很好,但在动态生成打印预览时会挂起UI。

转换效果很好,欢呼。

private BitmapImage ConvertImage(string str) {
byte[] imgData = Convert.FromBase64String(str);
using (InMemoryRandomAccessStream ms = new InMemoryRandomAccessStream())
{
    using (DataWriter writer = new DataWriter(ms.GetOutputStreamAt(0)))
    {
        writer.WriteBytes(imgData);
        writer.StoreAsync.GetResults();
    }
    BitmapImage result = new BitmapImage();
    result.SetSource(ms);
    return result;
}}