2017-04-14 21 views
0

BufferedImageオブジェクトを使用することに対する唯一の懸念は、60000x32000という非常に大きな画像の場合、限られたJVMヒープ領域でOOMを使用してJVMをシャットダウンすることです。しかし、 ImageIO.readメソッドのJavaDocsでは、「コントロールキャッシング」について何か言われています。ImageIOの制御キャッシュの意味read

このコンテキストでは、制御キャッシングとは何ですか?

ImageIO.readは大きな画像のためにディスク上の画像のキャッシュを使用していますか?

はJavaDocsの以下ImageIO.read方法を参照してください。この文脈において

 /** 
     * Returns a <code>BufferedImage</code> as the result of decoding 
     * a supplied <code>File</code> with an <code>ImageReader</code> 
     * chosen automatically from among those currently registered. 
     * The <code>File</code> is wrapped in an 
     * <code>ImageInputStream</code>. If no registered 
     * <code>ImageReader</code> claims to be able to read the 
     * resulting stream, <code>null</code> is returned. 
     * 
     * <p> The current cache settings from <code>getUseCache</code>and 
     * <code>getCacheDirectory</code> will be used to control caching in the 
     * <code>ImageInputStream</code> that is created. 
     * 
     * <p> Note that there is no <code>read</code> method that takes a 
     * filename as a <code>String</code>; use this method instead after 
     * creating a <code>File</code> from the filename. 
     * 
     * <p> This method does not attempt to locate 
     * <code>ImageReader</code>s that can read directly from a 
     * <code>File</code>; that may be accomplished using 
     * <code>IIORegistry</code> and <code>ImageReaderSpi</code>. 
     * 
     * @param input a <code>File</code> to read from. 
     * 
     * @return a <code>BufferedImage</code> containing the decoded 
     * contents of the input, or <code>null</code>. 
     * 
     * @exception IllegalArgumentException if <code>input</code> is 
     * <code>null</code>. 
     * @exception IOException if an error occurs during reading. 
     */ 
     public static BufferedImage read(File input) throws IOException { 
      if (input == null) { 
       throw new IllegalArgumentException("input == null!"); 
      } 
      if (!input.canRead()) { 
       throw new IIOException("Can't read input file!"); 
      } 

      ImageInputStream stream = createImageInputStream(input); 
      if (stream == null) { 
       throw new IIOException("Can't create an ImageInputStream!"); 
      } 
      BufferedImage bi = read(stream); 
      if (bi == null) { 
       stream.close(); 
      } 
      return bi; 
     } 
+0

私は@ john16384があなたの質問に非常に正確に答えたと思います。ただし、ディスクキャッシュイメージを使用してOOMEを回避する場合は、私の['MappedImageFactory'](https://github.com/haraldk/TwelveMonkeys/blob/master/sandbox/sandbox-common/src/main/)を試すことができます。 java/com/twelvemonkeys/image/MappedImageFactory.java)。 'ImageReadParam.setDestination(mappedImage)'を使うことによって、 'ImageIO'をこれらのイメージに直接読み込ませることができます。 – haraldK

+0

これはCMYKカラースペースファミリでも機能しますか? – t6nand

+0

私はそう信じています。しかし、私は試していないし、いつものようにコードは無保証で来る。あなたは何を信じて、それはうまくいかないでしょうか? – haraldK

答えて

2

を、それだけread方法は、キャッシング(getUseCache)許可される場合に制御するgetUseCachegetCacheDirectoryの設定を使用する手段とその場合、一時ファイル(getCacheDirectory)を格納できる場所。

ImageIOのキャッシュは素晴らしいとは言えません。おそらく、シーク不可能なストリームを扱うためのものです。たとえば、ImageIOがイメージのサイズを決定する必要がある場合、ストリームのかなりの部分を読み取る必要があります。次に、実際のデコードを行うために、ストリームのその部分を再び読み直す必要があるかもしれません。

シークをサポートするファイルとストリームの場合、デコードを開始するときに前の部分を再読み込みするだけで問題ありません。 HTTPストリームの場合、そのようなオプションはなく、そのような場合には、後でデコードするためにストリームの一部をどこかに格納する必要があるかもしれません。これはメモリ(MemoryCacheImageInputStream)またはテンポラリファイル(FileCacheImageInputStream)にある可能性があります。

使用されるストリームのタイプは、キャッシュ設定とその基礎となるメディアに基づいてこれを動的に決定するImageIOクラスまでです。

非常に大きな画像を扱うときには、これが役立つとは思っていません。 VMのデコードに十分なスペースがあることを確認する必要があります。

+0

有用な洞察をいただきありがとうございます。 – t6nand

関連する問題