views:

265

answers:

1

When i try to set the Source of WPF Image to a Image file that is ~11MB size and Shot in 14 MeagaPixcel Camera, the memory shoots up to around 170 MB when the image is rendered on the screen and the memory also never comes down after Rendering. If i try to do the same using .Net 2.0 Picturebox control the memory utilized is only .5MB to 1MB. Logically if the file size of an image is 11MB then it should at the maximum occupy only 11MB while rendering right? What is the cause of such behaviour in WPF? and is there any way to dispose the extra junk of memory after the rendering is compeleted on the screen?

+2  A: 

To answer the first part of your question:

Images shot on digital cameras are stored as jpg files and hence compressed. When read into memory it will be uncompressed. This accounts for the difference in size you are seeing here.

For example a photo shot on a Canon EOS 450 has a file size on disk of 3 MB. It's dimensions are 3072 x 2048. This leads to a size in memory of 3072 * 2048 pixels * 24 bits / pixel = 18,874,368 bytes (does that make sense - I'm never 100% sure of these calculations)

The memory usage won't come down until the object holding the image data falls out of scope and is cleared by the garbage collection.

For example you'll need something along the lines of this code:

using (Image image = Image.FromFile(imageName))
{
    // Non property item properties
    FileName = imageName;
    PixelFormat = image.PixelFormat;
    Width = image.Size.Width;
    Height = image.Size.Height;

    foreach (PropertyItem pi in image.PropertyItems)
    {
        EXIFPropertyItem exifpi = new EXIFPropertyItem(pi);
        this.propertyItems.Add(exifpi);
    }
}

Once I've got all the information I need from the image the using statement allows the garbage collection to kick in and free the memory.

ChrisF
That's an important thing to realize. Once read from disc and put in an image object (GDI+, normal .NET, or WPF), the image is basically a bitmap instead of jpg/png/gif
colithium
Thanks ChrisFYour answer does makes sence thanks, but my doubt is related to the rendering mechanism used in WPF. While creating image using any of the BitmapSource, the momory remains constant, but only when the image is rendered on the screen it takes up all the memory according to the Size of the image.When i compared this with the Picturebox control of .Net 2.0 and set the SizeMode of the Picturebox control to SizeMode.Zoom i can see that it does not use up any memory or what ever memory used up is immediately disposed even if the Picturebox has the Image rendered on it.
Does the rendering take another copy, while the PictureBox control uses the data directly? I don't know - just suggesting it as a line of inquiry.
ChrisF
I am not sure about how exactly the rendering works in Picturebox and the Image control. I think the problem is with the .Net Framework 3.5 and its rendering mechanism. I have posted an issue to the MS Connect team hoping to get a solution from them.In case you find a round-about by then then do let me know.Thanks