【发布时间】: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