• Advertisement
Sign in to follow this  

Maximum image size of a WriteableBitmap?

This topic is 721 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've tried to load a massive (16,320 x 16,200 @ 32mb) PNG into my project using this line:

 
        static WriteableBitmap bmpScreenshots = BitmapFactory.New(1, 1).FromResource("Images/Screenshots.png");

...and when I attempt to run I get an exception dialog saying:

 

An unhandled exception of type 'System.TypeInitializationException' occurred in mscorlib.dll

Additional information: The type initializer for 'MyTest.Program' threw an exception.

 

The output says:

Exception thrown: 'System.OutOfMemoryException' in PresentationCore.dll
An unhandled exception of type 'System.TypeInitializationException' occurred in mscorlib.dll
 
...however if I chop the image down to about 9,200 x 9,200 @ 9mb, the image loads and behaves correctly. If I increase it to about 9,600 x 9,600 I get the message again.
 
The exception appears linked to either the dimensions or physical size of the image file. I kept an eye on RAM usage before and during execution and RAM jumps from 4gb to 4.5gb out of 16gb so it surely can't be an actual Out of Memory problem. Does anyone know what could be wrong?
 

Share this post


Link to post
Share on other sites
Advertisement
By the way, your large image dimensions total to approximately 1 gb.

If you don't need WriteableBitmap specifically, you could use an alternative library such as devIL or ImageMagick to load it.

The .net out-of-the-box image loaders tend to make a memory mapping against the source file when loading, so as to save physical memory, but the address space still gets reserved.

Share this post


Link to post
Share on other sites
And, a classical way to fight such limits is to divide the image to tiles and show them one at a time when needed. This way, your memory is only limited by the long-term storage capacity (hdd).

Share this post


Link to post
Share on other sites

Thank you for your help Nik02. I was forgetting that even though the PNG file is "only" 32mb, it was being unpacked to an uncompressed bitmap in RAM and therefore will be far larger.

 

I need to think carefully about this - basically I have three of these PNGs totalling about 100mb. They are tilesets of screenshots (320x200 pixels each), that need to be selected from and displayed (blitted) to an existing WriteableBitmap - the visible UI. I chose WB because I thought the WriteableBitmapEx extension library was quite powerful and just what I needed. The user will be able to scroll through a huge list of these screenshots, and so I thought it best to load them all in up-front and Blit to my heart's content from the massive library onto the UI bitmap.

 

I still have all of these screenshots individually, in 9000 PNG files. I guess it is possible to load them individually as and when needed, but the UI of my project is quite dynamic graphically and the HDD will be being thrashed quite a lot as images are brought in as the user scrolls through the list.

 

Is there a possible way of loading the PNGs into RAM, keeping them compressed @ 100mb in total, and only 'unpacking' the rectangles I need from them to a background image as and when needed, so I can blit from there onto the UI? Perhaps a different library to WB, but a library that allows me to 'unpack' a RAM-held library PNG (or rather, a portion of it, i.e. the screenshot I want to see next) onto a WB.

 

Share this post


Link to post
Share on other sites

It is very possible to load the compressed files to memory and unpack them when you need to display them. Simply load them to byte vectors and when you need the Bitmap object from the data, initialize that from memory instead of from a file.

 

Note that scroll viewer virtualization (as in not keeping all items in memory) is a very common performance optimization technique in data-heavy user interfaces.

 

In combination with the aforementioned things, you could use an alternative PNG library that lets you specify the rectangle to load from the image, while not consuming the memory for the rest of the image. The format itself makes this possible, but I don't know specific libraries off the top of my head that can achieve this.  

Share this post


Link to post
Share on other sites

Thanks Nik02. I decided to make a few tweaks to what I wanted to UI to achieve and found that I could do away with having all of the images at their full sizes and have a trade-off where I have all images as thumbnails in RAM, and load full size images from HDD when required. So I basically redesigned my way out of the problem! :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement