在Java中将大图像加载为缩略图而不存在内存问题?
我试图让用户从硬盘加载图像,并在GUI中以缩略图列表的形式直观地显示这些图像(带有添加到JList的图标的JPanel)。我目前正在使用ImageIO.read()获取BuffereImage,并对每个映像使用GetScaleInstance(听说您不应该使用它) 它可以很好地处理小图像,但是加载了四张以上的照片(5000x3000或类似的照片),我得到了“java.lang.OutOfMemoryError:java堆空间”。未保存对完整大小BuffereImage的引用,因此我认为垃圾收集器会处理它,只保留缩放的映像(这不应该占用太多内存),但它看起来不像。我也使用了getRuntime().gc()和System.gc(),但没有效果 有什么好方法可以从文件中加载缩放图像,而不会出现内存错误?显然,很多软件都能做到这一点,但可能不是用Java实现的。外部图书馆没问题在Java中将大图像加载为缩略图而不存在内存问题?,java,memory-management,image-processing,thumbnails,Java,Memory Management,Image Processing,Thumbnails,我试图让用户从硬盘加载图像,并在GUI中以缩略图列表的形式直观地显示这些图像(带有添加到JList的图标的JPanel)。我目前正在使用ImageIO.read()获取BuffereImage,并对每个映像使用GetScaleInstance(听说您不应该使用它) 它可以很好地处理小图像,但是加载了四张以上的照片(5000x3000或类似的照片),我得到了“java.lang.OutOfMemoryError:java堆空间”。未保存对完整大小BuffereImage的引用,因此我认为垃圾收集器
当前代码:
BufferedImage unscaledImage = ImageIO.read(imageFile);
int unscaledHeight = unscaledImage.getHeight();
int unscaledWidth = unscaledImage.getWidth();
int imageRatio = unscaledHeight/unscaledWidth;
if (imageRatio >= 1) {
return new ImageIcon(unscaledImage.getScaledInstance(width,-1,Image.SCALE_FAST));
} else {
return new ImageIcon(unscaledImage.getScaledInstance(-1,height,Image.SCALE_FAST));
}
问题在于BuffereImage本身的使用。当文件被读入内存时,堆空间就用完了。根据其用途,您可以使用图像读取器,也可以增加堆的大小 我建议你使用图像阅读器。例如,要获取图像读取器,您需要编写如下代码:
// Create an image input stream on the image
ImageInputStream iis = ImageIO.createImageInputStream(o);
// Find all image readers that recognize the image format
Iterator iter = ImageIO.getImageReaders(iis);
if (!iter.hasNext()) {
// No readers found
return null;
}
// Use the first reader
ImageReader reader = (ImageReader)iter.next();
发件人:
如果您有ImageReader,则可以通过调用reader.getAspectRatio()
我不知道你是如何从图像阅读器变成缩略图的 JVM有一个讨厌的习惯,就是缓存图像。绕过它的一种方法是:
InputStream
字节[]
(使用标准I/O API-外部imageio
等)字节[]
创建一个ByteArrayInputStream
ByteArrayInputStream
作为ImageIO.read(InputStream)
的源请注意,我找不到任何支持我所说内容的文件。这只是过去的经验。太好了。在使用ImageReader.read(0,ImageReadParam)获取BuffereImage之前,使用ImageReadParam.getSourceSubSampling(wratio,hratio,0,0)对其进行缩放非常有效。@SWEn0thing。酷,我必须记住如何获得缩略图。我还需要添加以下调用。ImageReadParam params=reader.getDefaultReadParam();reader.setInput(iis,true,true);参数设置资源子采样(宽度、高度、0、0);