gpt4 book ai didi

Java:读取图像并显示为 ImageIcon

转载 作者:IT王子 更新时间:2023-10-28 23:38:19 26 4
gpt4 key购买 nike

我正在编写一个应用程序,它将图像读取并显示为 ImageIcons(在 JLabel 中),该应用程序需要能够支持 jpegs 和位图。

对于 jpeg,我发现将文件名直接传递给 ImageIcon 构造函数可以正常工作(即使显示两个大 jpeg),但是如果我使用 ImageIO.read 获取图像然后将图像传递给 ImageIcon 构造函数,我会得到读取第二个图像时出现 OutOfMemoryError(Java Heap Space)(使用与之前相同的图像)。

对于位图,如果我尝试通过将文件名传递给 ImageIcon 进行读取,则不会显示任何内容,但是通过使用 ImageIO.read 读取图像然后在 ImageIcon 构造函数中使用该图像可以正常工作。

我从阅读其他论坛帖子中了解到,这两种方法对不同格式的工作方式不同的原因是 java 与位图的兼容性问题,但是有没有办法解决我的问题,以便我可以使用没有 OutOfMemoryError 的位图和 jpeg 的方法相同?

(如果可能,我希望避免增加堆大小!)

OutOfMemoryError 由这一行触发:

img = getFileContentsAsImage(file); 

方法定义为:

public static BufferedImage getFileContentsAsImage(File file) throws FileNotFoundException { 
BufferedImage img = null;
try {
ImageIO.setUseCache(false);
img = ImageIO.read(file);
img.flush();
} catch (IOException ex) {
//log error
}
return img;
}

堆栈跟踪是:

Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
at java.awt.image.DataBufferByte.<init>(DataBufferByte.java:58)
at java.awt.image.ComponentSampleModel.createDataBuffer(ComponentSampleModel.java:397)
at java.awt.image.Raster.createWritableRaster(Raster.java:938)
at javax.imageio.ImageTypeSpecifier.createBufferedImage(ImageTypeSpecifier.java:1056)
at javax.imageio.ImageReader.getDestination(ImageReader.java:2879)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:925)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:897)
at javax.imageio.ImageIO.read(ImageIO.java:1422)
at javax.imageio.ImageIO.read(ImageIO.java:1282)
at framework.FileUtils.getFileContentsAsImage(FileUtils.java:33)

最佳答案

您的内存不足,因为 ImageIO.read() 返回一个未压缩的 BufferedImage,它非常大并且保留在堆中,因为它被 图像图标。但是,Toolkit.createImage 返回的图像仍保持其压缩格式(使用私有(private) ByteArrayImageSource 类。)

您无法使用 Toolkit.createImage 读取 BMP(即使您可以,它仍会在内存中保持未压缩状态,并且您可能会再次耗尽堆空间),但您可以做的是读取将未压缩的图像以压缩形式保存在字节数组中,例如

public static ImageIcon getPNGIconFromFile(File file) throws IOException {
BufferedImage bitmap = ImageIO.read(file);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
ImageIO.write(bitmap, "PNG", bytes);
return new ImageIcon(bytes.toByteArray());
}

这样,未压缩的位图必须保存在内存中的唯一时间是在加载或渲染时。

关于Java:读取图像并显示为 ImageIcon,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2544759/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com