2012-04-11 8 views
2

Ich habe die folgenden zwei Funktionen Bytes zu Bild und Anzeige auf Bild in WPFKann nicht jpeg dekodieren mit JpegBitmapDecoder

private JpegBitmapDecoder ConvertBytestoImageStream(byte[] imageData) 
     { 
      Stream imageStreamSource = new MemoryStream(imageData);    

      JpegBitmapDecoder decoder = new JpegBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default); 
      BitmapSource bitmapSource = decoder.Frames[0]; 

      return decoder; 
     } 

Der obige Code funktioniert nicht überhaupt zu konvertieren. Ich bekomme immer die Ausnahme, dass "Keine Bildgebungskomponente gefunden" Bild wird nicht angezeigt.

private MemoryStream ConvertBytestoImageStream(int CameraId, byte[] ImageData, int imgWidth, int imgHeight, DateTime detectTime) 
    { 
     GCHandle gch = GCHandle.Alloc(ImageData, GCHandleType.Pinned); 
     int stride = 4 * ((24 * imgWidth + 31)/32); 
     Bitmap bmp = new Bitmap(imgWidth, imgHeight, stride, PixelFormat.Format24bppRgb, gch.AddrOfPinnedObject()); 
     MemoryStream ms = new MemoryStream(); 
     bmp.Save(ms, ImageFormat.Jpeg); 
     gch.Free(); 

     return ms; 
    } 

Diese Funktion funktioniert, ist aber sehr langsam. Ich möchte meinen Code optimieren.

+0

Es ist mir nicht ganz klar, welche 'imageData' Sie an' ConvertBytestoImageStream' übergeben. Ist es ein JPEG-Puffer oder handelt es sich um rohe Pixeldaten? – Clemens

+0

Es ist ein Jpeg-Puffer – xaria

Antwort

4

Ihre ConvertBytestoImageStream funktioniert gut für mich, wenn ich es einen JPEG-Puffer übergeben. Es gibt jedoch ein paar Dinge, die verbessert werden könnten.

private BitmapDecoder ConvertBytesToDecoder(byte[] buffer) 
{ 
    using (MemoryStream stream = new MemoryStream(buffer)) 
    { 
     return BitmapDecoder.Create(stream, 
      BitmapCreateOptions.PreservePixelFormat, 
      BitmapCacheOption.OnLoad); // enables closing the stream immediately 
    } 
} 

oder so::

private ImageSource ConvertBytesToImage(byte[] buffer) 
{ 
    using (MemoryStream stream = new MemoryStream(buffer)) 
    { 
     BitmapDecoder decoder = BitmapDecoder.Create(stream, 
      BitmapCreateOptions.PreservePixelFormat, 
      BitmapCacheOption.OnLoad); // enables closing the stream immediately 
     return decoder.Frames[0]; 
    } 
} 

Beachten Sie, dass anstelle der Verwendung JpegBitmapDecoder dieser Code ein nutzt Je nachdem, ob Sie wirklich einen Decoder oder ein Bitmap zurückkehren möchten, könnte das Verfahren auf diese Weise geschrieben werden statische Factory-Methode der abstrakten Basisklasse BitmapDecoder, die automatisch den richtigen Decoder für den bereitgestellten Datenstrom auswählt. Daher kann dieser Code für alle von WPF unterstützten Bildformate verwendet werden.

Beachten Sie auch, dass das Stream-Objekt in einem using block verwendet wird, das sich darum kümmert, es zu entsorgen, wenn es nicht mehr benötigt wird. BitmapCacheOption.OnLoad sorgt dafür, dass der gesamte Stream in den Decoder geladen wird und danach wieder geschlossen werden kann.

+0

Okay, mein Fehler, der übergebene Puffer ist Bitmap-Puffer selbst. Also, wie kann ich diesen Code verbessern GCHandle gch = GCHandle.Alloc (ImageData, GCHandleType.Pinned); int Schritt = 4 * ((24 * imgBreite + 31)/32); Bitmap bmp = neues Bitmap (imgWidth, imgHeight, Schritt, PixelFormat.Format24bppRgb, gch.AddrOfPinnedObject()); MemoryStream ms = neu MemoryStream(); bmp.Save (ms, ImageFormat.Jpeg); gch.Free(); – xaria

+0

Danke Clemens die BitmapSource.Create funktioniert – xaria