Large image eating away at my memory

houlahan

New member
Joined
Jul 16, 2009
Messages
3
Programming Experience
1-3
Ok so i have an jpg image of around 8.10mbs at around 13424 x 11344 pixels, i need to load the whole image in to a scrolling picturebox, is they anyway to do this without using so much memory.
thanks in advance.
 

Robert_Zenz

Well-known member
Joined
Jun 3, 2008
Messages
503
Location
Vienna, Austria
Programming Experience
3-5
The picture needs at least 600+ MB RAM just to be shown...though, you could try to 'trick' the picturebox.

Check how much the memory is if you load it as an Image (Image.FromFile()), if this is way less then showing it, then you could crop the image to fit the picturebox. Implement the scroll controls your self, and only render the part which is shown in the picturebox (f.e. draw the picture with the specified offset to a new image which has the size of the picturebox).
 

houlahan

New member
Joined
Jul 16, 2009
Messages
3
Programming Experience
1-3
Unfortunatly that wouldn't work as the picture is a map an the user scrolls and plots points on the map which then adds the coords in to a file depending on the x and y of where the user has clicked.
 

VicJ

Well-known member
Joined
Aug 12, 2008
Messages
79
Programming Experience
5-10
EDIT: I have probably been underestimating the problem. If so, sorry about that. I'll leave the text below for the while in case there is something useful.





Sure it will work. You just add the x and y scroll offset values to the x and y click coordinates. (Or subtract them, depending on which way you calculate the offset).

For an example of how to use Robert's method you may find it useful to look at this on the Code Project: CodeProject: Pan and Zoom Very Large Images. Free source code and programming help (I don't agree with everything there; you could use a picture box as long as you use its Paint sub instead of setting its image or background image. That would have the advantage that the pb is already double buffered.)

However you do it, the approach requires you to read the whole map image into memory. Was that what you wanted to avoid? I guess it must be possible to do something like the following:

1. Preprocess the map so you can store just the pixel data. Use Bitmap.Lockbits and Marshall.Copy to put all the pixels into an integer or byte array.
2. Save the array. The file will be a lot larger than the original image since it no longer has jpeg compression. But if you use it instead of the original image file, there is no need to read the whole file into memory at once.
3. When you want to get at part of the image, work out which part of the array you need and use a FileStream to read the appropriate part of the file.
4. Create a bitmap for the area to be drawn, and use LockBits to create a corresponding array. Then copy the filestream data into the array.

Obviously, this would be a lot more complicated than just reading the jpeg file, but if it works it should be possible to handle images whose size is limited only by storage. I haven't tried it but I will one of these days. Has anyone here already done something like this?

bye, VicJ
 
Last edited:
Top Bottom