Imagefrom.File(). Out of memory exception

你离开我真会死。 提交于 2021-01-29 08:33:54

问题


I am trying to load about 60 pictures in a list. Each picture is about 1MB. For 20 pictures no problem but above that I get Out of memory exception on the code line below. I have searched vastly of related issues, some stating about "using" key word and stream but since I am a beginner can someone please help me.

Image image = Bitmap.FromFile(Filename);

Here is my code

  private void LoadBtn_Click_1(object sender, EventArgs e)
    {
        OpenFileDialog newDialog = new OpenFileDialog();
        if (newDialog.ShowDialog() == DialogResult.OK)
        {
            images.Clear();

            string dirPath  = System.IO.Path.GetDirectoryName(newDialog.FileName.ToLower()); 
            DirectoryInfo di = new DirectoryInfo(dirPath);
            FileInfo[] finfos = di.GetFiles("*.*");

            foreach (FileInfo fi in finfos)
            {
                string ext = fi.Extension.ToLower();
                if ((ext.Equals(".png")) || (ext.Equals(".jpg")) || (ext.Equals(".tif")) ||                  (ext.Equals(".gif")))
                {
                    string Filename = fi.FullName;
                    Image image = Bitmap.FromFile(Filename); //exception occurs HERE
                    images.Add(image);
                    //this.imageList1.Images.Add(image);
                    //image.Dispose();
                }
            } 
        }

        pictureBox3.Image = images[0];

    }

I am using C#, windows forms. thanks


回答1:


After taking a look at the software you mentioned, as I told you you don't need to load the whole image in memory if you only need a thumbnail.

So I'd create I class

class ImageAndThumb
{
    public Image Thumb;
    public Image Big;
    private string ImagePath;
    public ImageAndThumb(string fileName)
    {         
        ImagePath = fileName;
        Image image = Image.FromFile(fileName)
        Image thumb = img.GetThumbnailImage(200, 200, ()=>false, IntPtr.Zero);
    }
    public Image LoadBigImage()
    {
        Big = Image.FromFile(ImagePath);
        return Big;
    }
    public void UnloadImage()
    {
        Big = null;
    }

}

Now we use that class:

List<ImageAndThumb> Images = new List<ImageAndThumb>();
  private void LoadBtn_Click_1(object sender, EventArgs e)
    {
        OpenFileDialog newDialog = new OpenFileDialog();
        if (newDialog.ShowDialog() == DialogResult.OK)
        {
            Images.Clear();

            string dirPath  = System.IO.Path.GetDirectoryName(newDialog.FileName.ToLower()); 
            DirectoryInfo di = new DirectoryInfo(dirPath);
            FileInfo[] finfos = di.GetFiles("*.*");

            foreach (FileInfo fi in finfos)
            {
                string ext = fi.Extension.ToLower();
                if ((ext.Equals(".png")) || (ext.Equals(".jpg")) || (ext.Equals(".tif")) ||                  (ext.Equals(".gif")))
                {
                    string Filename = fi.FullName;
                    ImageAndThumb image = new ImageAndThumb(Filename); 
                    Images.Add(image);
                }
            } 
        }

        pictureBox3.Image = Images[0].Thumb; // << Much less memory usage;

    }

And now whenever you need to use an image load it first For example:

void ShowPicture(int index)
{
    Images[index].LoadBigImage();
    PictureBoxBig.image = Images[index].Big;
}
void ClosePicture(int index)
{
    Images[index].UnloadImage();
}

one good idea is to unload an image once you load another:

int currentPictureIndex = -1;
    void ShowPicture(int index)
    {
        Images[index].LoadBigImage();
        PictureBoxBig.image = Images[index].Big;
        if(CurrentPictureIndex > -1) ClosePicture(CurrentPictureIndex);
        currentPictureIndex = index;
    }



回答2:


First of all, are you running out of memory ? Cause if you are then the error is valid.

If you are not running out of memory the first thing you will need to do is wrap the code in your foreach loop in a try/catch block as follows:

foreach (FileInfo fi in finfos)
{
    string ext = fi.Extension.ToLower();
    if ((ext.Equals(".png")) || (ext.Equals(".jpg")) || (ext.Equals(".tif")) || (ext.Equals(".gif")))
    {
        try 
        {
            string Filename = fi.FullName;
            Image image = Bitmap.FromFile(Filename); //exception occurs HERE
            images.Add(image);
            //this.imageList1.Images.Add(image);
            //image.Dispose();
        }
        catch {}
    }
} 

The reason for that is, as Jason Watkins mentioned in the comments it might as well be another form of error that just appears as an out of memory exception because of the lack of error messages in the Class.



来源:https://stackoverflow.com/questions/15584202/imagefrom-file-out-of-memory-exception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!