1

我想将一些 java.awt.Image 对象保存到磁盘中。但是当我尝试像:

for (Image image : images) {
    image = new ImageIcon(image).getImage();
    BufferedImage temp = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
    Graphics2D g = temp.createGraphics();
    g.drawImage(image, 0, 0, null);
    g.dispose();
    File tempFile = null;
    try {
        tempFile = File.createTempFile("img", ".jpg");
        ImageIO.write(temp, "jpg", tempFile);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    files.add(tempFile);
}

我收到 java 堆空间错误。

我需要把

image = new ImageIcon(image).getImage();

加载所有像素,以便 image.getwidth(null) 和 image.getHeight(null) 返回有效结果。

除了增加堆大小之外,还有其他方法可以做到这一点吗?

4

2 回答 2

1

您可以通过不将所有图像保存在然后迭代的集合中来节省一些堆。取而代之的是,在获得图像时检索并写入每个图像。我建议的代码的hasMoreImages()scanner.getNextImage()部分是对此的一种可能实现。

我还质疑使用 Graphics 上下文绘制图像是否明智,因为它可能已经处于可以使用 ImageIO 编写的状态。ImageIO.write() 需要 RenderedImage,因此快速实例检查可能就足够了。

while( hasMoreImages() ) {
    Image image = scanner.getNextImage();

    if ( image instanceof RenderedImage) ) {
        File tempFile = File.createTempFile( "img", ".jpg" );
        ImageIO.write( (RenderedImage)image, "jpg", tempFile );
        files.add( tempFile );
    } else {
        // Do your ImageIcon code thing here.
    }
}
于 2009-08-02T20:19:57.680 回答
1

您的问题是扫描仪图像非常 ——在 600 dpi 时,我们说的是每张彩色 A4 页面有超过 100 MB 的未压缩图像。好的扫描仪可以以数千 DPI 进行扫描——在 2000 DPI 时,单个未压缩的彩色页面将超过 1 GB。高质量扫描的大小让大多数人在第一次开始使用它们时毫无准备。

除非您正在运行具有大量 RAM 的 64 位操作系统,否则您永远无法在内存中容纳超过几张图像。以黑白或灰度和较低的分辨率进行扫描会有所帮助,但最好的解决方案是改变您处理图像的方式。

不要在内存中获取图像的集合——一次获取每个图像的一部分,然后写出图像直到完成。让您的 TWAIN 驱动程序和 API 工作——让它通过图像的部分缓冲区传递给您,直到完成。您可能最好使用 Java 库来执行此操作,而不是滚动您自己的图像处理


编辑:Java TWAIN 库的链接

于 2009-08-03T15:57:58.123 回答