2017-06-13 3 views
-1

Ich entwickle eine wissenschaftliche Bildaufnahmeanwendung, bei der aufeinanderfolgende Webcam-Frames als Einzelbilder gespeichert werden (im Gegensatz zur Videokodierung).Verhindern, dass BitmapDecoder SystemOutOfMemoryException verursacht

Dateien werden in ein ZIP-Archiv gespeichert, und wenn die Erfassung für die Analyse geladen wird, jedes Mal, wenn der Rahmen an einer bestimmten Stelle abgefragt wird, ein BitmapFrame wird durch das Verfahren LoadImage() in der folgenden Klasse erzeugt:

public class ImagemCinemetria 
{ 
    public int Index { get; private set; } 

    public byte[] ImageBytes { get; private set; } 

    public BitmapSource Imagem 
    { 
     get 
     { 
      if (_imagem == null) 
       _imagem = LoadImage(); 
      return _imagem; 
     } 
    } 
    BitmapSource _imagem; 


    // CONSTRUTOR 
    public ImagemCinemetria(int index, byte[] jpegBytes) 
    { 
     Index = index; 
     ImageBytes = jpegBytes; 
    } 



    private BitmapSource LoadImage() 
    { 
     using (var stream = new MemoryStream(ImageBytes)) 
     { 
      var decoder = new JpegBitmapDecoder(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad); 
      return decoder.Frames.First(); 
     } 
    } 
} 

Das Problem ist, sobald ich anfange, die Aufnahme zu navigieren (durch Verschieben eines Schiebereglers ähnlich einem Video-Player) und die BitmapFrames Start geladen werden, gibt es einen riesigen Speicherverbrauch und ziemlich bald bekomme ich eine SystemOutOfMemoryException.

Ich weiß vage, dass es einige Cache-Optionen für WPF-Bitmaps gibt, aber ich bin mir nicht sicher, was zu tun ist.

Antwort

0

Nun, ich fand selbst eine Lösung.

Was auch immer der Grund, warum JpegBitmapDecoder so viel Speicher belegt, das eigentliche Problem ist, dass die Eigenschaft ImagemAufenthalte für die ganze Klasse Lebensdauer im Speicher referenziert.

ich losgeworden die OutOfMemoryException durch den Lazy-Laden durch eine Eigenschaft Getter zu ersetzen, die das BitmapFramede novo jedes Mal schafft es heißt:

Also statt

public BitmapSource Imagem 
{ 
    get 
    { 
     if (_imagem == null) 
      _imagem = LoadImage(); 
     return _imagem; 
    } 
} 
BitmapSource _imagem; 

I Now haben

public BitmapSource Imagem => LoadImage(); 
Verwandte Themen