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

2024-03-02

我有 13255 张图像,每张图像宽度为 240 x 240 像素,最大大小为 15,412 字节,最小大小为 839 字节。

我试图循环遍历文件夹,将它们添加到 File[] 中。一旦我有了每个图像的数组,我就将它们放入 BufferedImage[] 中,准备好循环并绘制到由每个单独的图像组成的更大的单个图像上。

每个图像的命名形式为

图像 x-y.png

但是,我总是遇到 java.lang.OutOfMemoryError: Java heap space 错误。我不知道为什么。我尝试通过将参数添加到 Eclipse 目标的末尾来更改 JVM 可用的内存大小。以下是我用过的:

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

and

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)

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

Regards,

Jamie


您不需要将所有块图像保存在内存中。您可以一张一张地阅读它们,并在最终循环中绘制最终图像,如下所示:

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++;
    }
}

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • Java 类查找工具

    任何经常使用 Java 的人都知道类路径中的多个 jar 会给我们带来多少麻烦 我正在寻找一个可以帮助我的工具 在 jar 中搜索类文件类路径 在 jar 中搜索类文件具体位置 也许要求太多 但请告诉我同一个类是否存在于多个罐子中 不用说它
  • 使用 BlobOutputStream 在 Azure 中上传 blob

    我正在尝试直接从流上传 blob 因为我不知道我决定尝试的流的长度这个答案 https stackoverflow com a 24621538 3695939 这不起作用 即使它从流中读取并且不会抛出任何异常 内容也不会上传到我的容器 我
  • 创建通用数组时出错

    public class TwoBridge implements Piece private HashSet
  • Java中如何合并两个数组?

    它不是连接而是合并两个数组 使它们成为名称值对的数组 firstarray a aa aaa secondarray b bb bbb result a b aa bb aaa bbb 最好的方法是什么 in Java public sta
  • Java中如何对对象数组进行排序?

    我的数组不包含任何字符串 但它包含对象引用 每个对象引用都通过 toString 方法返回名称 id 作者和发布者 public String toString return name n id n author n publisher n
  • Java:将二维字符串数组打印为右对齐表格

    是什么best打印a的单元格的方法String 数组作为右对齐表 例如 输入 x xxx yyy y zz zz 应该产生输出 x xxx yyy y zz zz 这似乎是一个should能够完成使用java util Formatter
  • 使用 SSL 和代理设置的 Rest 客户端获取连接超时

    我正在使用带有忽略 ssl 的 Rest 客户端 它工作正常 但在将来我尝试使用客户端证书进行的生产中将无法工作 我有 ca 证书和客户端证书 我用它创建了一个客户端 但我收到错误 Exception in thread main com
  • 使用 Microsoft REST API - Java 将 Xbox-Live GamerTag 转换为 XUID

    我有一个 Java 应用程序 它需要能够获取用户输入的 Minecraft Bedrock Edition 玩家标签 并将其转换为给定帐户的 XUID 以便我可以将其存储起来以供稍后列入白名单和参考目的 我一直在浏览 Microsoft R
  • Map:为 Integer 和 Double 类型定义方法,但不为 String 类型定义方法

    我正在尝试定义一个方法putIfGreaterThan 为了我的新Map class 给定一个键 仅当新值大于旧值时 它才会用新值替换旧值 我知道我可以通过组合来实现这一点 通过有一个private final Map
  • 如何组合 3 个或更多 CompletionStages?

    如果有 2 个 CompletionStages 我可以将它们与thenCombine method CompletionStage a aCompletionStage getA CompletionStage b bCompletion
  • Java:如果数组大小未知,如何初始化?

    我要求用户输入 1 到 100 之间的一些数字并将它们分配到一个数组中 数组大小未初始化 因为它取决于用户输入数字的次数 我应该如何分配数组长度 如果用户输入 5 6 7 8 9 5 个数字 则 int list becomes int l
  • 在实现接口的类上强制使用单例模式

    我最好用一个例子来解释这个问题 我有一个接口模型可用于访问数据 模型可以有不同的实现 可以以各种格式表示数据 例如 XMl txt 格式等 Model不关心格式 可以说这样的一个实现是myxml模型 现在我想强迫myxml模型以及其他所有实
  • Netty Nio java 中的通信

    我想在 Netty nio 中创建一个具有两个客户端和一个服务器的通信系统 更具体地说 首先 我希望当两个客户端与服务器连接时从服务器发送消息 然后能够在两个客户端之间交换数据 我正在使用本示例提供的代码 https github com
  • 如何根据从 jtextfield 和组合框接收的值将数据行添加到 Jtable

    我有一个JFrame表格有JTextFields JCombobox等等 我能够将这些值接收到变量 现在我想将接收到的数据添加到JTable当用户单击 添加 或类似的操作时在新行中 我创造了JTable使用 net beans 的问题是将这
  • 从 Java 应用程序读取的文件是否会调用系统调用?

    我的理解是 请求文件系统路径 例如 aFile 的用户应用程序将调用文件系统并获取所请求文件的虚拟地址 然后应用程序将尝试以该地址作为参数 即作为 CPU 指令 进行读 写操作 执行读取命令时 内存管理单元会将该地址转换为物理地址 并查看页
  • 图标和导航视图之间的左边距

    我必须在图标和图标之间添加左边距NavigationView 如下图中箭头所示 我知道根据谷歌规范 这个边距必须有16dp但我需要改变它 我努力了
  • 运行 Espresso 测试时在 Android studio 中找不到属性 android:forceQueryable

    我已经使用 android studio 录制了我的 Android 应用程序 Espresso 测试记录浓缩咖啡测试选项中Run菜单 在记录的最后 我用自己的文件名保存了测试 单击保存按钮后 IDE 会自动在以下位置创建文件Android
  • Java 中的连接路径

    In Python我可以连接两条路径os path join os path join foo bar gt foo bar 我正在尝试在 Java 中实现相同的目标 而不用担心是否OS is Unix Solaris or Windows
  • Spring Data MongoDB 和批量更新

    我正在使用 Spring Data MongoDB 并且想要执行批量更新 就像此处描述的那样 http docs mongodb org manual reference method Bulk find update Bulk find
  • Swing GUI 出现 IntelliJ 错误“contentPane 无法设置为 null。”从终端编译时

    当我从 IntelliJ 编译我的项目时 没有任何问题 我的程序运行顺利 但是当我尝试使用 javac 从终端编译它时 警告 注意 Victor presentation TableControllerMenu java 使用未经检查或不安

随机推荐