none
To show a big bitmap in WPF lead to OutOfMemory exception. RRS feed

  • Question

  • Usage:

    To show a dynamically generated Bitmap in WPF. While zooming, the image should be recreated (not be resized).

    Problem:

    It's easy to throw out an OutOfMemory exception while the Bitmap is big(8000*8000)(~200+MB).

    Seems the memory usage is not released in time.

    Code:

    var memoryStream = new MemoryStream();
    if (bitmap != null)
    {
    bitmap.Save(memoryStream, ImageFormat.Bmp);
    bitmap.Dispose();
    }
    return BitmapFrame.Create(memoryStream);  // As the source of Image control

    It would be appreciated of you can give me some help.

    Friday, August 16, 2013 3:32 AM

Answers

  • I suppose you could try adding a GC.Collect. And if by any chance you're still using .NET 3.5 then consider moving to 4.x, AFAIR 3.5 does worse with such large bitmaps.

    If everything fails then I think the only remaining option is to split the image into multiple tiles and generate only those tiles that are visible. At a display resolution of 1920x1200 you only need around 20 MB for an image that fills the whole display, much less than 200 MB.

    • Marked as answer by AugustZ Friday, August 16, 2013 7:12 AM
    Friday, August 16, 2013 6:06 AM
    Moderator

All replies

  • For a start saving 200 MB in a MemoryStream is usually a bad idea. Consider using a temporary file for such large data. Or save the bitmap using ImageFormat.Png instead of Bmp but that would probably make it slower.

    Another thing you can try is to set the Source of the Image control to null before generating a new bitmap, this will allow the GC to collect the old bitmap. Otherwise both the old and new bitmaps will exist in memory for a while.

    Friday, August 16, 2013 5:06 AM
    Moderator
  • Mike, thank you a lot for your reply.

    Actually I tried the two approaches before and they do work for the most usual case.

    But sometimes, especially when I zooming quickly, the OutOfMemory exception would still thrown out.

    Do you have some more advice on this? Thank you.

    Friday, August 16, 2013 5:36 AM
  • I suppose you could try adding a GC.Collect. And if by any chance you're still using .NET 3.5 then consider moving to 4.x, AFAIR 3.5 does worse with such large bitmaps.

    If everything fails then I think the only remaining option is to split the image into multiple tiles and generate only those tiles that are visible. At a display resolution of 1920x1200 you only need around 20 MB for an image that fills the whole display, much less than 200 MB.

    • Marked as answer by AugustZ Friday, August 16, 2013 7:12 AM
    Friday, August 16, 2013 6:06 AM
    Moderator
  • GC.Collect doesn't help.

    I am using .NET3.5 and I can not decide to move to 4.x. And 4.x also has the similar issue as I test.

    I considered splitting the big one into small tiles, but I was afraid this would make it slower.

    Thank you a lot for your help. If you get any new idea, please share with me.

    Friday, August 16, 2013 7:12 AM