Мне нужно сделать несколько миниатюр из определенных частей большого изображения и сохранить их в виде изображений png/jpeg. Вот что я делаю:OutOfMemoryException при работе с изображениями в WPF
public static void Save(BitmapImage srcBitmap, Int32Rect srcRegion, Rect destRegion)
{
var cropped = new CroppedBitmap(srcBitmap, srcRegion);
var drawingVisual = new DrawingVisual();
using (DrawingContext drawingContext = drawingVisual.RenderOpen())
{
drawingContext.DrawImage(cropped, destRegion);
}
var bmp = new RenderTargetBitmap(256, 256, 96, 96, PixelFormats.Pbgra32);
bmp.Render(drawingVisual);
var bitmapEncoder = new PngBitmapEncoder();
bitmapEncoder.Frames.Add(BitmapFrame.Create(bmp));
using (var filestream = new FileStream(path, FileMode.Create))
{
bitmapEncoder.Save(filestream);
}
}
я могу назвать этот метод с использованием одного большого Bitmap
с различными srcRegion
в тысячу раз, приложение все больше потребляют больше памяти и, наконец, бросает System.OutOfMemoryException
! Кажется, утечка памяти в этой функции, но я не знаю, где она. Кто-нибудь может помочь?
EDIT: Также я не уверен, что это лучший способ получить часть большого изображения и изменить размер этой части на меньшее изображение (например, 256 * 256) и сохранить его. Есть ли лучшая идея?
Эта функция статична, что может быть причиной проблемы. Попробуйте удалить статический. Вы можете захотеть поместить код в отдельный класс, а затем удалить класс, чтобы обеспечить уничтожение объекта, чтобы предотвратить утечку. – jdweng
Используйте PerfView и делайте память - сделайте снимок кучи. Что ты видишь? https://www.microsoft.com/en-us/download/details.aspx?id=28567. Возможно, что с .NET 4.6.2 все становится лучше, если утечка связана с слишком ленивым характером GC и странным WPF-способом обработки неуправляемых ресурсов. Это может представлять интерес: http://geekswithblogs.net/akraus1/archive/2016/04/14/174476.aspx –
Является ли 'destRegion' когда-либо отличающимся от' (0, 0, 256, 256) 'и делает размер 'srcRegion' когда-либо отличается от' (256, 256) '? Если нет, возможно, вы можете напрямую передать CroppedBitmap в BitmapEncoder, не используя DrawingVisual и RenderTargetBtmap. – Clemens