Как избавиться от объекта BitmapDecoder в приложении wpf - PullRequest
2 голосов
/ 04 июня 2009

Я разработал приложение WPF, используя BitmapDecoder для сохранения изображений. При сохранении изображений я получаю

недостаточно памяти для завершения операции исключение.

Код выглядит примерно так:

BitmapDecoder imgDecoder = BitmapDecoder.Create(mem,
BitmapCreateOptions.IgnoreColorProfile, BitmapCacheOption.None);

Я думаю, что объект BitmapDecoder может быть причиной этого исключения; как распоряжаться объектом?

Ответы [ 3 ]

4 голосов
/ 24 февраля 2010

Я столкнулся с той же проблемой. У меня есть приложение, которое загружает тысячи изображений с помощью BitmapDecoder и сталкивается с проблемами памяти. Мне пришлось создать класс-оболочку ImageFileHandler, который обрабатывал все взаимодействия с BitmapDecoder, затем я сохранил свой экземпляр BitmapDecoder в WeakReference. Поэтому, если ОС требовалась память, мой слабый эталон отказывался бы от BitmapDecoder, а затем каждый раз, когда мой ImageFileHandler нуждался в этом, при необходимости он создавал новый.

2 голосов
/ 16 мая 2014

Не только BmpBitmapDecoder, но и все декодеры (GifBitmapDecoder, PngBitmapDecoder, JpegBitmapDecoder, TiffBitmapDecoder) не являются одноразовыми классами, поэтому все, что вы можете сделать, чтобы избавиться от них, это сказать

_myDecoder = null; 
GC.Collect();

И пусть сборщик мусора сделает свое дело.

Если вы предпочитаете, вы можете создать пул BitmapDecoder с и загрузить свои изображения как FileStream, которые являются одноразовыми и содержат двоичные данные ваших изображений. Может быть, код ниже дает вам представление:

GC.Collect();
// Load the file stream if it hasn't been loaded yet
if (_imageDataStream == null)
    _imageDataStream = new FileStream(_imagePath, FileMode.Open, FileAccess.Read, FileShare.Read);
else
    _imageDataStream.Seek(0, SeekOrigin.Begin);

string extension = System.IO.Path.GetExtension(_imagePath).ToUpper();
if (extension.Contains("GIF"))
    _decoder = new GifBitmapDecoder(_imageDataStream, BitmapCreateOptions.PreservePixelFormat,
        BitmapCacheOption.OnDemand);
else if (extension.Contains("PNG"))
    _decoder = new PngBitmapDecoder(_imageDataStream, BitmapCreateOptions.PreservePixelFormat,
        BitmapCacheOption.OnDemand);
else if (extension.Contains("JPG") || extension.Contains("JPEG"))
    _decoder = new JpegBitmapDecoder(_imageDataStream, BitmapCreateOptions.PreservePixelFormat,
        BitmapCacheOption.OnDemand);
else if (extension.Contains("BMP"))
    _decoder = new BmpBitmapDecoder(_imageDataStream, BitmapCreateOptions.PreservePixelFormat,
        BitmapCacheOption.OnDemand);
else if (extension.Contains("TIF"))
    _decoder = new TiffBitmapDecoder(_imageDataStream, BitmapCreateOptions.PreservePixelFormat,
        BitmapCacheOption.OnDemand);
1 голос
/ 04 июня 2009

BitmapDecoder не является одноразовым. Просто убедитесь, что у вас нет ссылок на BitmapDecoder, если он вам больше не нужен, и GC выполнит свою работу и при необходимости соберет неиспользуемую память.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...