2017-02-28 19 views
0

我想在單獨的線程中加載圖像(如果可能的話),並且在加載圖像時顯示圖像尺寸的一些存根,但最後我想顯示圖像本身。Java:如何首先獲取圖像尺寸ASAP和SECOND獲取整個圖像呢?

這裏我發現https://stackoverflow.com/a/1560052/258483如何讀取尺寸而不讀取整個圖像。

現在,如果我想採取這個尺寸,那麼不想鬆散的工作完成並繼續這個,最終實現BufferedImage

+1

您是否在閱讀器上嘗試過'readImage(null)'或'read(0)'? –

+0

是的,但我不明白這個邏輯。我爲什麼要迭代讀者?有多少讀者?一個閱讀器可用的尺寸是否可用,另一個閱讀器是否有圖像? – Dims

+0

此外,我不unserstand,爲什麼我應該調用ImageReader#setInput雖然這個讀者是從該輸入獲得。爲什麼不自動設置? – Dims

回答

0

這裏有一種方法來實現背景閱讀,並儘快報告尺寸,然後繼續在後臺讀取圖像。

要嘗試從您的意見回答的問題:

  • 你並不需要遍歷讀者。下面的代碼不會,它只是測試是否至少有一個閱讀器可以讀取給定的格式,並嘗試使用該閱讀器閱讀。你可以,如果你想,迭代,並嘗試下一個讀者,如果第一個失敗以某種方式。但是這樣做的邏輯非常複雜,通常不需要,因爲通常只有零個或一個閱讀器。
  • 從理論上說,一個讀者可能會讀取尺寸,並且無法讀取圖像。但是,如上所述,這不是常見的情況。在不知道尺寸的情況下閱讀圖像數據通常是不可能的。
  • ImageReaderImageReader實例是可重用的(但不是線程安全的,所以不要在線程之間共享),並且可以用來讀取許多不同的輸入(以相同的格式)。所以這是API中的性能考慮因素,我猜。您也可以根據文件名獲取讀者,在這種情況下,您無論如何都需要以某種方式傳遞輸入。

如果您瞭解鏈接答案中的代碼,代碼應該是非常明瞭的。

public class BackgroundImageReader implements Callable<BufferedImage> { 

    private final Object input; 

    public BackgroundImageReader(File input) { 
     this.input = input; 
    } 

    public BackgroundImageReader(InputStream input) { 
     this.input = input; 
    } 

    @Override 
    public BufferedImage call() throws IOException { 
     try (ImageInputStream stream = ImageIO.createImageInputStream(input)) { 
      Iterator<ImageReader> readers = ImageIO.getImageReaders(stream); 

      if (readers.hasNext()) { 
       ImageReader reader = readers.next(); 

       try { 
        reader.setInput(stream); 

        updateImageDimensions(new Dimension(reader.getWidth(0), reader.getHeight(0))); 

        return reader.read(0); 
       } finally { 
        reader.dispose(); 
       } 
      } 
      throw new IOException("Could not read image"); 
     } 
    } 

    public void updateImageDimensions(Dimension dimension) { 
     // TODO: Implement callback mechanism 
    } 
}