2013-03-23 142 views
0

我试图在列表中加载大约60张图片。每张图片大约1MB。对于20张照片来说没有问题,但是在上面的代码行中,我得到了内存不足的异常。我搜索了很多相关的问题,一些说明“使用”关键词和流,但由于我是初学者,有人可以帮助我。Imagefrom.File()。内存不足异常

Image image = Bitmap.FromFile(Filename); 

这里是我的代码

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]; 

    } 

我使用C#,Windows窗体。感谢

+0

看看http://stackoverflow.com/questions/2610416/is-there-a-reason-image-fromfile-throws-an-outofmemoryexception-for-an-invalid-i – 2013-03-23 07:06:54

+0

感谢您的回复,但没有答案在那里符合我的问题。我的文件没有损坏,问题必须真正处理所有文件的大小。正在考虑是否有关于这种记忆问题的方式,因为我已经看到了完美的图片浏览器,而这正是我想要的。例如,这个项目“https://sourceforge.net/projects/picturefilter/”确实是我想要的,但我无法访问代码。只有.exe文件可用 – Basco 2013-03-23 07:30:01

回答

1

考虑看看你提到的那样,我告诉你,你不需要加载整个图像在内存中,如果你只需要一个缩略图软件后。

所以我想创建I级

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; 
    } 

} 

现在我们使用这个类:

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; 

    } 

而现在,每当你需要使用的图像加载它首先 例如:

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

一个好主意是,一旦你加载另一个卸载图像:

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

由于奥马尔 1)我的应用程序将加载在其中用户选择查看文件夹中可用的所有图像文件。所有这些图像将在列表视图子面板中显示为缩略图。 2)用户将使用下一个和后退按钮浏览要显示在主窗口上的下一个和上一个图像。 3)为什么我决定把所有的图像在一个列表中是因为我有一个功能,如果用户希望这将给颜色到所有图像。 请看看这个应用程序。它类似于我所需要的,sourceforge.net/projects/picturefilter – Basco 2013-03-23 08:52:45

+0

@Basco我编辑我的回答对你: – 2013-03-23 09:39:47

+1

感谢奥马尔,由于种种原因,我不知道形象画像= Image.FromFile(文件名)仅给出约45缩略图其余为空,但在修改代码后FileStream fs = new FileStream(fileName,FileMode。打开);我现在可以获得超过300个缩略图。谢谢你,我会用你推荐的方法 Image img = Image.FromStream(fs); – Basco 2013-03-23 11:48:18

0

首先,你运行的内存?因为如果你是那么错误是有效的。

如果你不运行的内存,你需要做的第一件事就是换行代码在你的foreach循环在try/catch块如下:

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 {} 
    } 
} 

的理由是,正如Jason Watkins在评论中提到的那样,它也可能是另一种错误形式,由于类中缺少错误消息而只是出现内存不足异常。