【问题标题】:What does control caching means in ImageIO readImageIO读取中的控制缓存是什么意思
【发布时间】:2017-09-10 11:14:11
【问题描述】:

我唯一担心使用 BufferedImage 对象是,对于 60000x32000 的非常大的图像,它会导致 JVM 在有限的 JVM 堆空间上关闭并出现 OOM。然而, ImageIO.read 方法的 JavaDocs 说明了“控制缓存”。

在这种情况下,什么是控制缓存?

这是否意味着 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;
        }

【问题讨论】:

  • 我认为@john16384 非常准确地回答了您的问题。但是,如果你喜欢使用磁盘缓存的图像来避免 OOME,你可以试试我的MappedImageFactory。通过使用ImageReadParam.setDestination(mappedImage),您可以让ImageIO 直接读取这些图像。
  • 这也适用于 CMYK 颜色空间系列吗?
  • 我相信是的。但我没有尝试过,并且像往常一样,代码没有保修。是什么让你相信它行不通?
  • 抱歉,有一个不知情的问题,可能是因为我最近在处理带有 CMYK 色彩空间的图像时遇到了一些问题。

标签: java caching image-processing bufferedimage javax.imageio


【解决方案1】:

在这种情况下,它只是意味着read 方法将使用来自getUseCachegetCacheDirectory 的设置来控制是否允许缓存(getUseCache),如果允许,它可以存储临时文件的位置( getCacheDirectory)。

ImageIO 中的缓存并没有什么特别之处,可能只是用于处理不可搜索的流。例如,当 ImageIO 需要确定图像的大小时,它可能需要读取流的很大一部分。然后它可能需要再次重新读取该部分流以进行实际解码。

对于支持查找的文件和流,这不是问题,因为您可以在开始解码时重新读取较早的部分。例如 HTTP 流,没有这样的选项,在这些情况下,可能需要将流的一部分存储在某个地方以便以后对其进行解码。这可以在内存中 (MemoryCacheImageInputStream) 或临时文件 (FileCacheImageInputStream)。

使用哪种类型的流取决于ImageIO 类,该类根据缓存设置和底层媒体动态决定。

所以,我认为这在处理非常大的图像时不会对您有所帮助。您仍然需要确保 VM 有足够的空间来解码它们。

【讨论】:

    猜你喜欢
    • 2017-04-29
    • 2023-03-12
    • 1970-01-01
    • 2015-03-22
    • 1970-01-01
    • 1970-01-01
    • 2012-09-18
    • 2023-03-25
    • 1970-01-01
    相关资源
    最近更新 更多