0

BufferedImage 객체를 사용하는 것에 대한 두려움은 제한된 JVM 힙 공간에서 OOM으로 JVM이 종료되는 결과가되는 60000x32000의 매우 큰 이미지입니다. 그러나 ImageIO.read 메서드의 JavaDocs는 "제어 캐싱"에 대해 뭔가를 말합니다.ImageIO 읽기에서 제어 캐싱의 의미는 무엇입니까?

이 컨텍스트에서 제어 캐싱이란 무엇입니까?

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

은 단지 제어 getUseCachegetCacheDirectory의 설정을 사용할 read 방법을 의미한다 (getUseCache)을하고 :

JavaDoc을 아래 ImageIO.read 방법 참조 그렇다면 임시 파일 (getCacheDirectory)을 저장할 수 있습니다.

ImageIO의 캐싱은 멋진 것이 아니며 검색 할 수없는 스트림을 처리 할 때만 사용할 수 있습니다. 예를 들어, ImageIO가 이미지의 크기를 결정해야 할 때 스트림의 상당 부분을 읽을 필요가있을 수 있습니다. 그런 다음 실제 디코딩을 수행하기 위해 스트림의 해당 부분을 다시 읽어야 할 수도 있습니다.

검색을 지원하는 파일 및 스트림의 경우 디코딩을 시작할 때 이전 부분을 다시 읽을 수 있으므로 문제가되지 않습니다. HTTP 스트림의 경우 이러한 옵션이 없으며 나중에 스트림을 디코딩하기 위해 스트림의 일부를 저장할 필요가있을 수 있습니다. 메모리 (MemoryCacheImageInputStream) 또는 임시 파일 (FileCacheImageInputStream)에있을 수 있습니다.

사용되는 스트림 유형은 캐시 설정 및 기본 미디어를 기준으로 동적으로 결정하는 ImageIO 클래스까지 남겨 둡니다.

매우 큰 이미지를 다룰 때 도움이된다고 생각하지 않습니다. VM의 디코딩 공간이 충분한 지 확인해야합니다.

+0

유용한 통찰력을 가져 주셔서 감사합니다. – t6nand