java.lang.OutOfMemoryError:将13k .png图像拼接在一起时的Java堆空间

我有13255个图像,每个240 x 240像素宽,最大的15,412字节大小和最小的839字节.

我试图循环文件夹将每个文件添加到File [].一旦我有一个每个图像的数组,然后我将它们放在BufferedImage []中,准备好循环并绘制到由每个图像组成的更大的单个图像上.

每个图像都以.的形式命名

Image x-y.png

但是,我一直以java.lang.OutOfMemoryError:Java堆空间错误结束.我不知道为什么.我已经尝试通过向Eclipse的目标末尾添加参数来更改JVM可用内存的大小.以下是我用过的内容:

IDE's\eclipse-jee-juno-SR2-win32-x86_64\eclipse\eclipse.exe -vmargs -Xms64m -Xmx1024m

IDE's\eclipse-jee-juno-SR2-win32-x86_64\eclipse\eclipse.exe -vmargs -Xms64m -Xmx4096m

两者都没有效果.我也进入了控制面板 – >程序 – > Java并改变了那里可用的内存量.

这是我写的方法:

public static void merge_images() throws IOException {
        int rows = 115; 
        int cols = 115;
        int chunks = rows * cols;

        System.out.println(chunks);

        int chunkWidth, chunkHeight;
        int type;
        // fetching image files
        File[] imgFiles = new File[chunks];

        int count = 0;
        for (int j = 1; j <= 115; j++) {
            for (int k = 1; k <= 115; k++) {
                imgFiles[count] = new File("G:\\Images\\Image " + j
                        + "-" + k + ".png");
                count++;
            }
        }
        System.out.println(imgFiles.length);

        // creating a buffered image array from image files
        BufferedImage[] buffImages = new BufferedImage[chunks];
        for (int i = 0; i < chunks; i++) {
            buffImages[i] = ImageIO.read(imgFiles[i]);
            System.out.println(i);
        }
        type = buffImages[0].getType();
        chunkWidth = buffImages[0].getWidth();
        chunkHeight = buffImages[0].getHeight();

        // Initializing the final image
        BufferedImage finalImg = new BufferedImage(chunkWidth * cols,
                chunkHeight * rows, type);

        int num = 0;
        for (int i = 0; i < rows; i++) {
            for (int k = 0; k < cols; k++) {
                finalImg.createGraphics().drawImage(buffImages[num], null,
                        chunkWidth * k, chunkHeight * i);
                num++;
            }
        }
        System.out.println("Image concatenated.....");
        ImageIO.write(finalImg, "png", new File("fusions.png"));
        System.out.println("Image Saved, Exiting");
    }

在这里的打印线

for (int i = 0; i < chunks; i++) {
            buffImages[i] = ImageIO.read(imgFiles[i]);
            System.out.println(i);
}

它总是停在7320点左右.

这是确切的控制台打印输出

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.awt.image.DataBufferByte.<init>(Unknown Source)
    at java.awt.image.ComponentSampleModel.createDataBuffer(Unknown Source)
    at java.awt.image.Raster.createWritableRaster(Unknown Source)
    at javax.imageio.ImageTypeSpecifier.createBufferedImage(Unknown Source)
    at javax.imageio.ImageReader.getDestination(Unknown Source)
    at com.sun.imageio.plugins.png.PNGImageReader.readImage(Unknown Source)
    at com.sun.imageio.plugins.png.PNGImageReader.read(Unknown Source)
    at javax.imageio.ImageIO.read(Unknown Source)
    at javax.imageio.ImageIO.read(Unknown Source)
    at main.merge_images(main.java:48)
    at main.main(main.java:19)

任何我出错的想法都将不胜感激.

问候,

杰米

解决方法:

您不需要将所有块图像保留在内存中.您可以逐个阅读它们并在最终循环中绘制到最终图像,如下所示:

for (int i = 0; i < rows; i++) {
    for (int k = 0; k < cols; k++) {
        BufferedImage buffImage = ImageIO.read(imgFiles[num]);
        finalImg.createGraphics().drawImage(buffImage, null,
                chunkWidth * k, chunkHeight * i);
        num++;
    }
}

这将节省至少一半的内存.

上一篇:java – 为什么使用ImageIO无法从URL获取BufferedImage


下一篇:java – 在JTable单元格中渲染BufferedImage