2013-03-23 4 views
0

목록에 약 60 장의 사진을로드하려고합니다. 각 그림은 약 1MB입니다. 20 장의 그림은 아무런 문제가 없지만 아래의 코드 줄에서 메모리 부족 예외가 발생합니다. 나는 관련 이슈들을 광범위하게 검색했다. 핵심 단어와 스트림을 "사용하는"것에 대해 언급 한 적이 있지만, 초보자부터 누군가 나를 기쁘게 도와 줄 수있다.Imagefrom.File(). 메모리 부족 예외

Image image = Bitmap.FromFile(Filename); 

여기에 내 코드

나는 C#을 사용하고
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]; 

    } 

, 창 형태입니다. 덕분에

+0

http://stackoverflow.com/questions/2610416/is-there-a-reason-image-fromfile-throws-an-outofmemoryexception-for-an-invalid-i –

+0

답장을 보내 주셔서 감사합니다. 하지만 거기에 대한 답은 내 문제와 일치하지 않습니다. 내 파일이 손상되지 않았으므로 문제는 실제로로드되는 전체 파일의 크기와 관련이 있습니다. 이 기억 문제에 대한 방법에 관한 이야기가 있다면 생각하고 있었기 때문에 내가 원하는 것을하는 깔끔한 그림을 보았습니다. 예를 들어,이 프로젝트 "https://sourceforge.net/projects/picturefilter/"는 정확히 원하는 것을 수행하지만 코드에 액세스 할 수 없습니다. .exe 파일 만 사용 가능 – Basco

답변

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

감사합니다. Omer 1) 내 응용 프로그램은 사용자가 파일을보기 위해 선택한 폴더에서 사용할 수있는 모든 이미지 파일을로드합니다. 이 모든 이미지는 목록보기 하위 패널에 미리보기로 표시됩니다. 2) 사용자가 주 창에 표시 할 다음 및 이전 이미지를 탐색하는 데 사용할 다음 및 뒤로 단추가 있습니다. 3) 모든 이미지를 목록에 넣기로 결정한 이유는 사용자가 원하는 경우 모든 이미지에 색상을 지정하는 기능이 있기 때문입니다. 이 애플리케이션을 살펴보십시오. 그것은 내가 무엇을 필요로 비슷합니다, sourceforge.net/projects/picturefilter – Basco

+0

@ 바스코 내가 내 대답을 편집 : –

+1

고마워요 오마르, 내가 알지 못하는 몇 가지 이유로 이미지 이미지 = Image.FromFile (fileName) 약 45 미리보기 이미지를 제공합니다 나머지는 null이지만 코드를 수정 한 후 FileStream fs = new FileStream (fileName, FileMode.열다); 이제 300 개 이상의 미리보기 이미지를 얻을 수 있습니다. 감사합니다 10 억, 당신이 추천 한이 방법을 사용합니다 이미지 img = Image.FromStream (fs); – Basco

0

우선 메모리가 부족합니까? 오류가 발생하면 오류가 발생합니다.

당신은 당신이해야 할 첫 번째 일은 다음과 같이 try/catch 블록에서 foreach 루프의 코드를 포장입니다 메모리가 부족하지 않은 경우 :

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)가 주석에서 언급했듯이, 클래스의 오류 메시지가 없기 때문에 메모리 부족 예외로 나타나는 또 다른 형태의 오류 일 수 있습니다.