2017-02-28 21 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 
    } 
}