2012-07-25 57 views
2

我正在編寫一個程序,涉及到許多圖像的自定義搜索。當用戶輸入他們的搜索條件時,相應的圖像將從緩存或服務器中獲取。我有一個顯示指向相應圖像的鏈接的JTable。當用戶點擊鏈接時,圖像顯示在JPanel上。點擊鏈接時,我可以從硬盤讀取圖像,但速度並不像我想的那麼快。加載它需要幾秒鐘的時間。我已經嘗試創建一個BufferedImage數組,但如果搜索返回許多結果,我去奧姆。我想知道什麼是點擊鏈接時更快速地顯示圖像的最佳方式。在java中加載很多緩衝圖像100+到內存

繼承人我如何獲取圖片...

Public void getFile(String fileName){ 
File file = new File("./cache/"+fileName); 
    boolean exists = file.exists(); 

    BufferedImage returnImage =null; 
    if(exists){ 
     try { 

      returnImage = ImageIO.read(file); 
      System.out.println("Found In Cache!"); 
     } catch (IOException|IndexOutOfBoundsException e) { 
      try { 
       if(fileName != null){ 
       returnImage = downloadImage(fileName); 
       System.out.println("Found ON Server :("); 
       } 
      } catch (IOException |IndexOutOfBoundsException ex) { 
       // TODO Auto-generated catch block 
       ex.printStackTrace(); 
      } 
     } 
    }else{ 
     try { 
      if(fileName != null){ 
      returnImage = downloadImage(fileName); 
      System.out.println("Found ON Server :("); 
      } 
     } catch (IOException |IndexOutOfBoundsException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
    return returnImage; 

} 
} 

而這正是我把它們放在一個數組...

BufferedImage[] images = new BufferedImage[numOfSearchResults]; 

for(SearchResult r: results){ 
    images[i] = imageCache.getFile(r.imageName); 
} 

基本上我只是想知道會是什麼最好的方式來預先加載圖像,而不會發生。提前致謝

+0

從磁盤加載圖像並顯示它不應該花費幾秒鐘,除非它是一個非常大的圖像(磁盤空間很大尺寸)。你有沒有分析你的應用程序,看看圖像加載是否確實是瓶頸? – Robin 2012-07-25 16:14:40

+0

什麼是奧姆? – 2012-07-25 16:15:52

+0

@SteveKuo我編輯了包含正確的標記。 – 2012-07-25 16:16:14

回答

3

從磁盤加載圖像需要幾秒鐘的時間,除非圖像真的真的是BIG(10萬像素或更多),這聽起來不合理。首先確定時間的真正用處。

對於緩存,您可以持有對使用java.lang.ref.SoftReference加載的每個圖像的引用 - 這允許您在運行OOM之前在之前對圖像進行垃圾回收。 如果真的不可避免,我會使用多層緩存系統,第一級使用內存中的SoftReferences,而基於服務器的映像使用額外的磁盤緩存。在查找映像時,首先檢查內存中的緩存,如果沒有發現任何內容,則檢查磁盤緩存,如果仍未找到,則以常用方式加載映像。

+1

圖像相當大3300 x 2550我用較小的圖像測試它,它們很快從磁盤讀取。謝謝 – Gamplod 2012-07-25 16:37:53

+0

是否可以只加載圖像的一部分?在這種大小和全分辨率下,不可能顯示所有的圖像,所以不妨像Photoshop那樣加載一個圖塊。 – 2013-03-21 02:35:57

+1

@JamesPoulson那麼,TC沒有說他使用的是什麼圖像格式,但對於通常的疑問JPG,PNG等,除非你編寫自己的圖像解碼器,否則沒有太多可以做的事情(我懷疑你可以獲得多少) 。 Photoshop btw。 *也*加載整個圖像。平鋪方法隨後用於在處理圖像時將圖像的各個部分交換到磁盤。它不能直接在通用的圖像文件上使用,比如說PNG。 – Durandal 2013-03-21 16:48:26

2

請勿加載所有/太多圖像,在當前索引之前加載耦合圖像,並在當前索引之後耦合圖像。

將圖像加載器實現爲不阻止主執行線程並在用戶正在觀看當前加載的圖像時加載額外圖像的另一個線程。

+0

我可能會看看Executors API的這個 – MadProgrammer 2012-07-25 16:21:24

0

您可以打開所有圖像的InputStream並關閉用戶未點擊的圖像,然後使用您需要的圖像。

通過這種方式,您不必緩衝所有圖像,但在用戶點擊時已將它們放在「可觸及範圍內」。

但是@Robin已經正確評論了,它真的不需要很長時間才能加載平均大小的圖片。

我不確定這是否會讓您獲得更多的表現,但取決於您的情況,它可以。

0

如果您不需要全尺寸圖像,我會在加載時縮小它們以減少內存量。您必須記住,內存中加載的圖像不再被壓縮。

如果您可以控制源圖像,我會考慮生成縮略圖以幫助它們加載更快。我們使用的是200x200,&的縮略圖,即使在基於SMB的共享上,他們也只需要一秒鐘的時間來加載