防止BitmapDecoder用于导致SystemOutOfMemoryException

时间:2017-06-13 13:28:17

标签: c# wpf out-of-memory imagesource

我正在开发一个科学的图像捕获应用程序,其中连续的网络摄像头帧被保存为单独的图像(而不是视频编码)。

文件保存到zip存档,当加载捕获进行分析时,每次查询给定位置的帧时,BitmapFrame都会生成LoadImage()以下的方法类:

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

问题是,一旦我开始导航捕获(通过移动类似于视频播放器的滑块光标)并开始加载BitmapFrames,就会消耗大量内存,很快我获得SystemOutOfMemoryException

我隐约知道WPF位图有一些缓存选项,但我不知道该怎么做。

1 个答案:

答案 0 :(得分:0)

我自己最终找到了解决方案。

无论JpegBitmapDecoder占用如此多内存的原因是什么,实际问题是属性Imagem 在内存中为所有类生命周期保留

我通过一个属性getter替换延迟加载来摆脱OutOfMemoryException,每次调用时都会创建BitmapFrame de novo

所以而不是

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

现在我有了

public BitmapSource Imagem => LoadImage();