2014-10-23 2 views
0

그래서 이미지 파일 경로 목록을 기반으로 1000 개의 미리보기 이미지를 채울 수 있기를 원합니다. 다음 코드를 사용하여 시도했지만 200 + 이미지 후 내 프로그램 "System.Drawing.dll에서 발생한 'System.OutOfMemoryException'형식의 첫 번째 기회 예외가 throw됩니다 깨달았다. 필요에 따라 listview에서 미리보기 이미지를로드하는 방법은 무엇입니까?

private void PopulateThumbnails(List<string> queryResults) 
{ 
    this.playerListView.Items.Clear(); 
    this.imageList1.Images.Clear(); 
    ImageViewer imageViewer = new ImageViewer(); 

    foreach (string file in queryResults) 
    { 
     try 
      this.imageList1.Images.Add(Image.FromFile(file)); 
     catch 
      Console.WriteLine("This is not an image file"); 
    } 

    this.ListView.View = View.LargeIcon; 
    this.imageList1.ImageSize = new Size(256, 144); 
    this.ListView.LargeImageList = this.imageList1; 

    for (int j = 0; j < this.imageList1.Images.Count; j++) 
    { 
     ListViewItem item = new ListViewItem(); 
     item.ImageIndex = j; 
     this.ListView.Items.Add(item); 
    } 
} 

는 내가 아마 단지 ... 필요에 따라 썸네일을 채우는해야하지만 실현 가) 어떻게 목록보기에로드되는 항목의 수를 알 수 있습니까? b) listview에서 스크롤 이벤트를 검색하려면 어떻게해야합니까?

+0

ListViewItem에 썸네일이나 이미지를 추가하는 방법에 대한 Google 검색은 이전의' 그럼'그 사이에 게시 http://stackoverflow.com/questions/17151776/c-sharp-listview-adding-item-with-image-and-text-and-align-the-text-to-left – MethodMan

+0

잘 내 문제는 미리보기 이미지를 추가하는 방법을 알지 못합니다. 있는 그대로 작동합니다. 너무 많은 썸네일을 추가하면 문제가 발생합니다. – JLYK

+0

어쩌면 코드를 디버깅하는 방법에 대해 잘 모르는 뭔가가있을 수 있습니다. ListView에 항목을 추가 한 후에이 줄에서 항목을 해제해야 할 수도 있습니다.Items'ListViewItem item = new ListViewItem();'그러나 코드를 통해 단계를 밟으면 뭔가 발견 할 수 있다고 생각합니다. – MethodMan

답변

0

이것은 다소 까다 롭습니다.

당신은 두 가지 문제가있다 : 당신은 당신이 메모리가 부족하지 않도록해야

  • 표시해야하는 이미지 알아야

    • 또는 GDI 리소스를

    불행히도 ListView은 스크롤에 대해 사용자에게 알리거나 표시되는 항목을 알려주는 이벤트 또는 속성에 도움이되지 않습니다.

    다음은 적어도 후자를 수행 할 코드 조각입니다. 이 목록의 이미지로 수천 파일 이름을로드하고 마지막으로 볼 수있는, 100 개 항목의 목록을 유지 :

    당신은 ListView.OwnerDraw = true;를 설정해야
    List<string> images = new List<string>(); 
    List<int> visibleItems = new List<int>(); 
    
    void listView1_DrawItem(object sender, DrawListViewItemEventArgs e) 
    { 
        // this loads the images on demand: 
        if (!imageList1.Images.ContainsKey(images[e.ItemIndex])) 
         { loadImage(e.ItemIndex); e.Item.ImageIndex = imageList1.Images.Count - 1; } 
        // this makes sure the listView is drawn by the system 
        e.DrawDefault = true; 
    
        // these lines would maintain a list of items that are or were recently visible 
        if (!visibleItems.Contains(e.ItemIndex)) visibleItems.Add(e.ItemIndex); 
        if (visibleItems.Count > 1000) 
        { 
         visibleItems.Clear(); 
         imageList1.Images.Clear(); 
         listView1.Invalidate(); 
        } 
    
    } 
    
    void loadImage(int index) 
    { 
        imageList1.Images.Add(images[index], new Bitmap(images[index])); 
    } 
    

    ; DrawItem 이벤트가 호출되고 e.DrawDefault = true;을 설정하면 실제 그리기가 시스템에 의해 수행됩니다.

    하지만 이벤트는 계속 표시되는 항목을 정확하게 알려줍니다. 나는처럼 Plutonix : 이제

    당신이 .. 각각의 비트 맵이 당신의 ImageList에서로드 또는 그 멀리 다시 배치되어 있는지 확인 할 수 있습니다 지금까지 난 단지에만 ..

    업데이트 요구에 부하를 구현 runa 테스트를 거치지 않고 문제가없는 128x128 픽셀의 3000 이미지를로드 할 수 있습니다. 이미지를 처리 ​​할 필요가 없으므로 GDI 리소스는 저의 첫 번째 프로그램에 대해 낮은 레벨 (< 100)을 유지합니다. 스크롤하는 동안 메모리가 계속 증가하지만 문제가있는 것처럼 보이지 않습니다. 그것은 내가 할 수있는 일이다.

    imageList1.Images.Clear(); 
    

    그리고 메모리가 시작 지점으로 떨어진다. 표시 잘 작동, 목록 재로드는 결함없이 시작됩니다. 사실 더 이상 visibleItems 목록을 사용하지 않습니다. 나는이 항목들에 대해 알 수있는 실현 가능한 방법이기 때문에 대답에 그것을 유지하지만, 나는 그것을위한 필요성을 알지 못한다 ..

  • 관련 문제