15

Ich arbeite an einer Windows 8 Metro App, die Filter auf Bilder anwendet. Ich habe eine Webversion der App und wollte sie portieren. Aber wie wir alle wissen, hat WinRT nicht all die guten Dinge, die .NET ansonsten bietet:/C# Windows 8 Store (Metro, WinRT) Byte-Array zu BitmapImage

Derzeit bin ich die Filter auf eine Byte-Array anwenden und ich möchte es so behalten, weil es super schnell ist! In den letzten paar Tagen habe ich nach Möglichkeiten gesucht, eine StorageFile in Byte [] und dann Byte [] in BitmapImage zu konvertieren.

Bis jetzt habe ich es geschafft, die erste (StorageFile zu Byte []) zu tun. Hier ist, wie ich es tun:

public async Task<Byte[]> ImageFileToByteArray(StorageFile file) 
    { 
     IRandomAccessStream stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read); 
     BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream); 
     PixelDataProvider pixelData = await decoder.GetPixelDataAsync(); 
     return pixelData.DetachPixelData(); 
    } 

Dieses Stück Code ein byte[] zurückgibt, der die Pixeldaten als BGRA enthält.

Und hier kommt der knifflige Teil. Ich kann das Bytearray nicht erfolgreich in ein BitmapImage konvertieren. Ich habe überall gesucht und viele Leute schlagen vor, WriteableBitmap zu verwenden, aber das tut mir nicht viel Gutes. Ich habe auch einige Code-Teile gefunden, die funktionieren sollten ... aber das tun sie nicht.

Eine der Lösungen, die ich versucht habe nutzt InMemoryRandomAccessStream wie folgt aus:

public async Task<BitmapImage> ByteArrayToBitmapImage(Byte[] pixels) 
    { 
     var stream = new InMemoryRandomAccessStream(); 
     await stream.WriteAsync(pixels.AsBuffer()); 
     stream.Seek(0); 
     var image = new BitmapImage(); 
     await image.SetSourceAsync(stream); 
     return image; 
    } 

Dieses wirft die folgende Ausnahme:

Eine Ausnahme vom Typ 'System.Exception' trat in mscorlib. dll aber wurde nicht im Benutzercode behandelt

Zusätzliche Informationen: Die Komponente kann nicht gefunden werden. (Ausnahme von HRESULT: 0x88982F50)

Ich habe versucht, diese Zeile anstelle:

PixelDataProvider pixelData = await decoder.GetPixelDataAsync(
      BitmapPixelFormat.Bgra8, 
      BitmapAlphaMode.Ignore, 
      new BitmapTransform(), 
      ExifOrientationMode.IgnoreExifOrientation, 
      ColorManagementMode.DoNotColorManage); 

Aber es tat mir nicht gut, da ich immer diese Ausnahme zu bekommen.

Ich habe auch schon versucht, diese:

var bitmapImage = new BitmapImage(); 
     var pixels = await ImageFileToByteArray(file); 
     ImageSource imgSource; 
     using (InMemoryRandomAccessStream ms = new InMemoryRandomAccessStream()) 
     { 
      using (DataWriter writer = new DataWriter(ms.GetOutputStreamAt(0))) 
      { 
       writer.WriteBytes(pixels); 
       await writer.StoreAsync(); 
      } 

      await bitmapImage.SetSourceAsync(ms); 
      imgSource = bitmapImage; 
     } 

Und die gleiche Ausnahme wie das erste Stück Code bekommen.

Ich habe auch verschiedene andere Möglichkeiten ausprobiert, die einen normalen Stream verwenden und dann in einen IRandomAccessStream konvertieren, aber sie haben auch nicht funktioniert.

All der obige Code scheint mir gut. Also meine Vermutung im Moment ist, dass das Problem in der byte[] ist. Ich nehme an, dass das Format der pixelData im Inneren nicht gültig ist, also habe ich versucht, es in RGBA zu ändern, aber das hat auch nicht geholfen. Auch die PixelHeight und Pixelwidth des Bitmap 0.

+0

Haben Sie eine Lösung gefunden? Ich habe auch das gleiche Problem. – TheQuestioner

Antwort

12

Dies ist für mich arbeiten,

private async Task<BitmapImage> ByteArrayToBitmapImage(byte[] byteArray) 
    { 
     var bitmapImage = new BitmapImage(); 

     var stream = new InMemoryRandomAccessStream(); 
     await stream.WriteAsync(byteArray.AsBuffer()); 
     stream.Seek(0); 

     bitmapImage.SetSource(stream); 
     return bitmapImage; 
    } 
+0

musste auf Null (stream.Seek (0)) arbeiten, um zu arbeiten :) vielen Dank :) –

1

dies ist mein erster answer..hope es wird helfen.

Ich hatte genau das gleiche Problem und ich spand mehr als 6 Stunden versuchen, dies herauszufinden. das ist was ich dachte: was du gesagt hast, war richtig.gibt es 2 waye Bild byteArray zu konvertieren:

Erstes aproach (verkaufen)

 public async Task<byte[]> ImageFileToByteArrayAsync(StorageFile file) 
    { 
     IRandomAccessStream stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read); 
     BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream); 
     PixelDataProvider pixelData = await decoder.GetPixelDataAsync(); 
     return pixelData.DetachPixelData(); 
    } 

Zweite aproach

 public async Task<byte[]> ImageFileToByteArrayAsync(StorageFile file) 
    { 
     var inputStream = await file.OpenSequentialReadAsync(); 
     var readStream = inputStream.AsStreamForRead(); 
     var buffer = new byte[readStream.Length]; 
     await readStream.ReadAsync(buffer, 0, buffer.Length); 
     return buffer; 
    } 

wenn youll den zweiten aproach verwendet das Bild zu dekodieren, ohne Pixel, dieser Konverter funktioniert:

public class ByteArrayToImageConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, string language) 
    { 
     if (value == null || !(value is byte[])) 
      return null; 

     using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream()) 
     { 
      using (DataWriter writer = new DataWriter(stream.GetOutputStreamAt(0))) 
      { 
       writer.WriteBytes((byte[])value); 
       writer.StoreAsync().GetResults(); 
      } 
      BitmapImage image = new BitmapImage(); 
      image.SetSource(stream); 
      return image; 
     } 
    } 
    public object ConvertBack(object value, Type targetType, object parameter, string language)                   
    { 
     throw new NotImplementedException(); 
    } 

für den ersten Ansatz, den Sie mit Writeabl arbeiten müssen eBitmap wie du gesagt hast.