2013-03-23 141 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在評論中提到的那樣,它也可能是另一種錯誤形式,由於類中缺少錯誤消息而只是出現內存不足異常。