2016-05-23 18 views
2

In meiner UWP-App speichere ich Bilder in einer SQLite-Datenbank in Form von byte []. Wenn ich dann meine Objekte aus der Datenbank abrufe, binde ich sie an eine GridView-Datenvorlage, die ein Image-Steuerelement besitzt. Als ich das Bild der Quelle direkt an das Array binden kann nicht, so habe ich eine Bitmap Eigenschaft in meinem Objektklasse erstellt die Bildsteuerung zu binden:UWP BitmapImage SetSource aus MemoryStream hängt

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

Das Problem ist, hängt meine App auf dem img.SetSource Linie . Nach einigem Experimentieren habe ich festgestellt, dass dieses Problem mit einem zweiten Memory überwunden werden kann:

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

Aus irgendeinem Grunde funktioniert es, nicht hängen. Ich wundere mich warum? Und wie kann man mit dieser Situation richtig umgehen? Vielen Dank!

Antwort

4

Ich schlage vor, dass Sie die IValueConverter-Schnittstelle verwenden, bevor Sie das Bild in Ihrer App anzeigen.

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

Die perfekt für mich und das hängende Problem in meinem Projekt gearbeitet hatte, von diesen Datawriter fest. Vielen Dank für Ihre Informationen. –

0

Warum nicht Base64 verwenden? Speichern Sie Base64 Image in der sqlite-Datenbankspalte und binden Sie es einfach an Image control.

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

es ist viel einfacher, Bild in Gridview von sqlite db zu binden.

+0

Base64 erhöht die Speichernutzung – Tsayper

1

Ich verwende eine Erweiterung Methode, die ich in den Konverter verwenden:

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