Click here to Skip to main content
15,883,901 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Hello!
I design an application in which i would like to slide images and read text files from multiple directory.I read each image from folder and store it in list of type image.There are more than 3500 images resides in one main directory.So my problem is that, when I am trying to load all images in list;it gives me exception 'Out of Memory'.
I tried lot options but it behaves same.Here below I copied code snippets of that logic.Give me some hint about error in logic or datatype used.
C#
try {
	if (Directory.Exists(dirName)) {
	loadedImages = new List<Image>();//Create object of list which declared globally
	try {//Take file names of current directory into string array fileEntries
        	fileEntries = Directory.GetDirectories(dirName);
		for (int i = 0; i < fileEntries.Length; i++) {
               //Read file from each subdirectory.
		DirectoryInfo dir = new DirectoryInfo(fileEntries[i]);
		foreach (FileInfo f in dir.GetFiles("*.png")) {
		if (IsValidImage(f.FullName)) {//validate image by checking header of it
			loadedImages.Add(Image.FromFile(f.FullName));//Add image into list named as loadedImages
		}
	   }
        }
} catch (Exception exc) { MessageBox.Show(exc.Message + "Error while collecting images", "Get image error"); }
Posted
Comments
johannesnestler 28-Apr-15 10:41am    
I would ask why you want to hold 3500 Images in memory? Better use a different approach. Just construct a list of FileInfos (or just the paths) for all the Images. Then load/unload them on demand while "sliding" (whatever that means in your application) - if the user views the images in a kind of "list" maybe consider "virtualizing" it, so that you only hold the visible Images in memory...
Valery Possoz 28-Apr-15 17:41pm    
I agree 100%. That's the way to go.
Sergey Alexandrovich Kryukov 28-Apr-15 18:10pm    
I've shown some simplest way to provide a load-on-call image collection; please see Solution 1.
—SA
Tomas Takac 28-Apr-15 10:44am    
johannesnestler is right, you must not load so much data into memory. You need to solve the problem in different way.
Sergey Alexandrovich Kryukov 28-Apr-15 18:10pm    
Right. Please see Solution 1.
—SA

1 solution

It makes absolutely no sense to load all those images in memory at once. Keep the images in the directory and create a container which holds only the image names. Better yet, rename all files to have the same names as some integer index, better in hexadecimal form. Then you can have the class with the indexed access to images. Don't forget to forget image references when an image is no longer displayed. This is needed to make the reference unreachable, so the GAC could eventually destroy them. Also, you would need to Dispose() each image when it is no longer needed.

It could look something like:
C#
using System.Drawing;

// ...

    class ImageCollection {

        internal Image[] array = //... initialize new array when you populate
        
        Image this[int index] {
            get { // load on call:
                Image image = array[index];
                if (image != null) return image;
                // for example
                string imageFileName = string.Format("{0:X8}", index);
                image = Image.FromFile(imageFileName);
                array[index] = image;
                return image;
            }
        }

        internal void Forget(int index) {
            Image image = array[index];
            if (image == null) return;
            image.Dispose();
            array[index] = null;
        }

        // some methods for collection population ...

    }

Here, you just assume that Directory.GetFiles give you the count of files with file names in one directory with the names based on hexadecimal numbers 00000000, 00000001,… 0000000A, etc. Initially, you create the array with Count of null values. Each time you need a file at some index, and find that the image is not presently in the list (it's null), you calculate the file name and load it to the array element, and later use it. You can forget some elements when they are no longer displayed. This is important: you cannot keep them all loaded at the same time.

—SA
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900