0

Meine einzige Angst Objekt BufferedImage die Verwendung ist, dass die für ein sehr großes Bild sagen 60000x32000 es in JVM heruntergefahren mit OOM auf einem begrenzten JVM-Heap-Raum führen. JavaDocs der ImageIO.read-Methode sagt jedoch etwas über "Control-Caching" aus.Was Caching Kontrolle tut bedeutet in ImageIO las

Was ist die Kontrolle Caching in diesem Zusammenhang?

Heißen das ImageIO.read verwendet Caching von Bild auf der Festplatte für großes Bild?

zu JavaDocs und ImageIO.read Methode unten Siehe:

 /** 
     * 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

Ich denke @ John16384 beantwortet Ihre Frage sehr genau. Wenn Sie jedoch zwischengespeicherte Bilder verwenden möchten, um OOME zu vermeiden, können Sie versuchen, meine ['MappedImageFactory'] (https://github.com/haraldk/TwelveMonkeys/blob/master/sandbox/sandbox-common/src/main/ Java/com/zwölf Monkeys/Bild/MappedImageFactory.java). Mit 'ImageReadParam.setDestination (mappedImage)' können Sie 'ImageIO' direkt in diese Bilder einlesen lassen. – haraldK

+0

Würde dies auch für eine Familie von CMYK-Farbräumen funktionieren? – t6nand

+0

Ich glaube ja, ja. Aber ich habe es nicht versucht und wie üblich kommt der Code ohne Garantie. Was lässt dich glauben, dass es nicht funktioniert? – haraldK

Antwort

2

In diesem Zusammenhang, es bedeutet nur die read Methode werden die Einstellungen von getUseCache und getCacheDirectory zu steuern, wenn das Caching (getUseCache) erlaubt wird, benutzen und wenn ja, wo kann es temporäre Dateien speichern (getCacheDirectory).

Der Caching in ImageIO ist nichts Spektakuläres und wahrscheinlich nur mit nicht-seekable Ströme für den Umgang. Wenn z. B. ImageIO die Größe des Bilds bestimmen muss, muss möglicherweise ein wesentlicher Teil des Streams gelesen werden. Es muss dann möglicherweise erneut diesen Teil des Streams erneut lesen, um die eigentliche Decodierung durchzuführen.

Für Dateien und Streams, die Suche nach Unterstützung, ist dies kein Problem, da kann man einfach wieder liest einen früheren Teil, wenn die Dekodierungs starten. Für einen HTTP-Stream gibt es beispielsweise keine solche Option, und in diesen Fällen muss möglicherweise ein Teil des Streams irgendwo gespeichert werden, um ihn später zu decodieren. Dies kann im Speicher (MemoryCacheImageInputStream) oder in einer temporären Datei (FileCacheImageInputStream) erfolgen.

Welcher Stream-Typ verwendet wird, bleibt der ImageIO-Klasse überlassen, die dies basierend auf den Cache-Einstellungen und den zugrunde liegenden Medien dynamisch entscheidet.

So donot Ich denke, dies wird Ihnen helfen, wenn mit sehr großen Bildern zu tun. Sie müssen weiterhin sicherstellen, dass die VM über ausreichend Speicherplatz für die Decodierung verfügt.

+0

Danke für die nützlichen Einblicke. – t6nand