4

I am trying to convert a byte array of an image to BitmapImage to bind to a button.

public static BitmapImage GetBitmapImageFromByteArray(byte[] p_Image)
    {
        try
        {
            BitmapImage bmpImage;
            if (p_Image != null)
            {
                using (MemoryStream msStream = new MemoryStream(p_Image))
                {
                    msStream.Position = 0;
                    bmpImage = GetBitmapImageFromStream(msStream);
                    //msStream.Close();
                    return bmpImage;
                }
            }
        }
        catch
        {
        }
        return null;
    }

Where GetBitmapImageFromStream looks something like this:

public static BitmapImage GetBitmapImageFromStream(MemoryStream msImage)
    {
        try
        {
            if (msImage == null) return null;
                BitmapImage bmpImg = new BitmapImage();
                msImage.Position = 0;
                bmpImg.BeginInit();
                bmpImg.CacheOption = BitmapCacheOption.OnLoad;
                bmpImg.StreamSource = msImage;
                bmpImg.EndInit();
                return bmpImg;

        }
        catch
        {
            return null;
        }
    }

On bmpImg.EndInit(), there is this huge spike in memory. And I have many buttons on my interface which is causing issue. Why this is happening and how can I fix it or how to restore the memory?

Thanks.

user296623
  • 325
  • 3
  • 7
  • 18
  • 1
    While its doesnt solves your problem, but in the `GetBitmapImageFromStream` function you creates a `wrapper` stream that isn't referenced in the using statement. – Ben May 26 '11 at 19:17

2 Answers2

1

From the help my guess is that it creates a copy to cache it, and maybe one copy scaled down to use it on the button. And while the GC doesn't collect all the data that copied into the streams there will be multiple copies in the memory.

Ben
  • 1,023
  • 9
  • 10
  • Ben: With some research, I found what you have mentioned above but trying to figure out how to resolve. – user296623 May 26 '11 at 19:49
  • Can you explain your useage pattern? Where you use the images, how much images, what size they have? If you use a lots of images that always needs to be seen or referenced, than i think you can't avoid a big memory useage especially if you use big images. – Ben May 26 '11 at 20:27
  • Each image size is around 45KB. I have 30 custom buttons with each showing 4 images. So, its 120 images in total which can occupy upto 6 - 7 MB memory (120 x 44K). But my application is using about 1.2GB and I get Out of memory exception. – user296623 May 26 '11 at 20:56
  • There must be some bug somewhere, i recenlty wrote an editor to our artists that uses and displays more images(100-200 images with size is around 100-300KB) and its not using more than 250MB of memory. But my images loaded from disk. Maybe there are some reference to your byte array that prevents the GC to collect it? How big that memory spike when you creates a BitmapImage? – Ben May 26 '11 at 21:08
  • Its around 5000KB for each image. – user296623 May 26 '11 at 21:12
  • What is the resolution and color depth of the images? Size on disk is not always equal to size in memory. – Emond May 27 '11 at 05:56
  • Both horizontal and vertical resolutions are 96 dpi and color depth is 8 bits per pixel – user296623 May 27 '11 at 13:21
0

Try to limit your image height. You can set DecodePixelHeight property to BitmapImage. It will take some time to convert you bytes but max height will be limited and memory usage will be reduced.

                var bmpImg = new BitmapImage();
                msImage.Position = 0;
                bmpImg.BeginInit();

                 bmpImg.DecodePixelHeight =containerHeight; 

                bmpImg.CacheOption = BitmapCacheOption.OnLoad;
                bmpImg.StreamSource = msImage;
                bmpImg.EndInit();
                return bmpImg;

P.s. Maybe you will have a memory leak there. http://code.logos.com/blog/2008/04/memory_leak_with_bitmapimage_and_memorystream.html

Ievgen
  • 4,261
  • 7
  • 75
  • 124