Search code examples
c#memory-mapped-files

How to work with memory mapped files when loading multiple large images


I have many georeferenced images of the US in png and tiff format. There are about 12 that I want to use. Each image is about 60mb and the resolution is about 18000*12000 pixels. I am trying to create a windows forms application that loads all of the images to create a map. (check out the link below--top pic).The program also has zoom/pan capability. I have tried loading about 4 images and the application gets really slow and it even crashes many times. So I want to know if I could use memory mapped files (or any other way). What I want to do is load only the portion of the images that is visible and not all of the images. When you zoom or pan, only the visible map part should load. I want to use memory mapped files for this but don't know where to start.

What I am trying to create


Solution

  • Our conversation in messages is getting a little long so I will turn this in to an answer.

    Don't use memory mapped files, use a tiled map system.

    For now I am just going to deal with a single 18000*12000 image but you can extend this logic to the multiple images you have. What you are going to do is you need to break it up in in to smaller lower resolution chunks to show to the user at a given time.

    So say you have 3 zoom levels 100%, 66%, and 33%. 100% would be the native resolution.

    So for 100% we break the image up in to smaller 250x250px images, so now you have 3,456 small 250x250 images (72 images across by 48 images down).

    For the 66% you either use a different source image to represent that "zoom level" (for example you might not show smaller roads on a map) or you can decrease the size of your original image. Lets say you decrease the image, you use a paint program to lower the resolution of your source image to 12000x8000, we once again break the image up in to smaller 250x250px images, so now you have 1,536 small 250x250 images (48 images across by 32 images down).

    We repeat the process again for 33% lower the resolution of your source image to 6000x4000, we once again break the image up in to smaller 250x250px images, so now you have 384 small 250x250 images (24 images across by 16 images down).

    So in your database you keep the 5,376 images you generated (3,456 + 1,536 + 384) Say the user has a useable screen resolution of 1920x1080, you would load 40 of the 250x250 tiles in memory (8 images across by 5 images down) for the appropriate zoom level and show them on screen. If your user pans or change zoom levels new tiles load and you let old tiles unload so you only need to keep 40 250x250 images in memory at any given time.