user294211
user294211

Reputation:

Out of memory with multi images in one picturebox

I have a problem with out of memory when I'm trying load a few images into one picturebox.

public void button2_Click(object sender, EventArgs e)
    {


        FolderBrowserDialog dialog = new FolderBrowserDialog();
        dialog.ShowDialog();
        string selected = dialog.SelectedPath;

        string[] imageFileList = Directory.GetFiles(selected);


        int iCtr = 0,zCtr = 0;
        foreach(string imageFile in imageFileList)
        {

            if (Image.FromFile(imageFile) != null)
            {
                Image.FromFile(imageFile).Dispose();
            }

            PictureBox eachPictureBox = new PictureBox();

            eachPictureBox.Size = new Size(100,100);
           // if (iCtr % 8 == 0)
            //{
             //   zCtr++;
              //  iCtr = 0;
            //}
            eachPictureBox.Location = new Point(iCtr * 100 + 1, 1);
            eachPictureBox.Image = Image.FromFile(imageFile);
            iCtr++;

            panel1.Controls.Add(eachPictureBox);

        }


    }`enter code here`

Upvotes: 1

Views: 4797

Answers (3)

Robert C. Barth
Robert C. Barth

Reputation: 23315

The picture box internally holds a reference to the bitmap that you place in it. Unless you get rid of the picture box, it's holding a reference to every bitmap you load into it.

Upvotes: 1

Paul Sasik
Paul Sasik

Reputation: 81429

Something you have to consider that regardless of the type of picture stored on disk, when you open it for display the picture will become a bitmap and require 4 bytes per displayed pixel.

Your code seems to suggest an attempt at a thumbnail operation. You are in fact loading 70 files into memory and regardless of the display size, in memory they will be very large.

For example let's say you have 70 jpegs at 32bit color depth and say 1920x1080 pixels in size. Your memory requirement to load that many images all at once then is:

 70 pics x 1920 pixels x 1080 pixels x 4 bytes/pixel = 580,608,000 bytes! 

And that's a fairly low estimate.

You could consider loading many fewer pictures or trying for a real thumbnailing solution.

Upvotes: 0

Adam Robinson
Adam Robinson

Reputation: 185593

if (Image.FromFile(imageFile) != null)
{
    Image.FromFile(imageFile).Dispose();
}

Bad. You're loading the image from the file, checking to see if the result is null...then loading it again into a new result so that you can dispose it. While the latter portion is silly, it isn't harmful. The first portion is, however, as the resulting Image is never properly disposed of (if/when the GC collects it, the finalizer on the Image type should dispose of the unmanaged resources, but this is not a wise thing to rely on).

Incidentally, Image.FromFile will never return null. If it cannot read the image, then it will throw an OutOfMemoryException.

The code also appears to do nothing, since there's no else block and nothing meaningful is done in the if block.

My guess is that your OutOfMemoryException is coming from the fact that one or more of the files in that directory is stored in a corrupted or unsupported image format, or isn't an image at all.

Try replacing the code in your foreach with this:

try
{
    Image image = Image.FromFile(imageFile);

    PictureBox eachPictureBox = new PictureBox();

    eachPictureBox.Size = new Size(100,100);

    eachPictureBox.Location = new Point(iCtr * 100 + 1, 1);
    eachPictureBox.Image = Image.FromFile(imageFile);
    iCtr++;

    panel1.Controls.Add(eachPictureBox);
}
catch(OutOfMemoryException) { } // skip the file

Upvotes: 1

Related Questions