Out of memory with multi images in one picturebox
Asked Answered
M

3

1

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`
Moss answered 15/3, 2010 at 18:43 Comment(2)
How many images are stored in the directory that you're selecting?Nw
You are loading several images, but each one into each picture box. So what's the error code? a try catch what yield?? Maybe too many images?Tiber
M
1
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
Mistral answered 15/3, 2010 at 18:46 Comment(1)
If you've found the answer helpful, please be sure to accept it.Mistral
R
1

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.

Rorie answered 15/3, 2010 at 19:1 Comment(0)
W
0

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.

Wittenburg answered 15/3, 2010 at 19:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.