简体   繁体   English

来自MemoryStream的UWP BitmapImage SetSource挂起

[英]UWP BitmapImage SetSource from MemoryStream hangs

In my UWP app i store images in an SQLite db in form of byte[]. 在我的UWP应用中,我将图像以byte []的形式存储在SQLite数据库中。 Then as i retrieve my objects from the db i bind them to a GridView data template which has an Image control. 然后,当我从数据库检索对象时,我将它们绑定到具有Image控件的GridView数据模板。 As i cant bind the Image's Source directly to the array, so i have created a BitmapImage property in my object's class to bind the Image control to: 由于我无法将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;
            }
        }
    }

The problem is, my app hangs on the img.SetSource line. 问题是,我的应用程序挂在img.SetSource行上。 After some experimenting, i have found that this problem can be overcome with a second MemoryStream: 经过一些试验,我发现可以使用第二个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;
            }
        }
    }

For some reason it works, does not hang. 由于某些原因,它不会挂起。 I wonder why? 我想知道为什么? And how to deal with this situation properly? 以及如何正确处理这种情况? Thanks! 谢谢!

i'll suggest you use the IValueConverter interface before showing the image in your app. 我建议您在应用程序中显示图像之前使用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();
    }
}

Why not to use Base64? 为什么不使用Base64? Save Base64 Image in sqlite database column and bind it to Image control easily. 将Base64图像保存在sqlite数据库列中,并将其轻松绑定到Image控件。

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

it is much easier to bind image inside Gridview from sqlite db. 从sqlite db绑定到Gridview内部的图像要容易得多。

I use an extension method that I use into the converter: 我使用在转换器中使用的扩展方法:

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

I've had an issues printing images loading from RandomAccessStreams until I found this. 在发现从RandomAccessStreams加载的图像之前,我一直遇到问题。 They load fine in the app for visual but would hang the UI when generating print previews dynamically. 它们在应用程序中的视觉效果很好,但在动态生成打印预览时会挂起UI。

Conversion works perfectly, cheers. 转换效果很好,欢呼。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM