Java OutOfMemoryError:jtable另存为映像时占用堆空间

Java OutOfMemoryError:jtable另存为映像时占用堆空间,java,jtable,bufferedimage,Java,Jtable,Bufferedimage,目前,我正在使用以下方法将jtable保存为jpeg,当jtable的维度变为2590126181,java.lang.OutOfMemoryError:BuffereImage构造函数发生java堆空间异常,当表的大小较小时,图像成功保存 public BufferedImage saveComponentAsJPEG(JTable table, String filename) { Dimension size = table.getSize(); BufferedImage

目前,我正在使用以下方法将jtable保存为jpeg,当jtable的维度变为2590126181,java.lang.OutOfMemoryError:BuffereImage构造函数发生java堆空间异常,当表的大小较小时,图像成功保存

 public BufferedImage saveComponentAsJPEG(JTable table, String filename) {
   Dimension size = table.getSize();
   BufferedImage myImage = 
     new BufferedImage(size.width, size.height,
     BufferedImage.TYPE_INT_RGB);
   Graphics2D g2 = myImage.createGraphics();
   table.paint(g2);  
   return myImage;    
 } 
如何在pdf或jpeg图像中保存较大尺寸的jtable?

更新信息:

您询问如何将JTable拆分为不同的小图像:

当您阅读下面的代码时,请阅读我的注释,它们有助于解释正在发生的事情,并帮助您更好地理解如何将JTable/JComponent绘制到许多小图像上。从本质上讲,我的代码与您的代码相似,但有两个关键点:

1我没有创建一个大的BuffereImage,而是创建一个小的映像,然后多次使用,因此留下了非常小的内存占用

2对于单个图像,我每次使用Graphics.translate绘制JTable的一小部分

使用大型JComponents 2590 x 126181和200x200的磁贴大小测试了以下代码,整个过程的内存不超过60mb:

//width = width of tile in pixels, for minimal memory usage try 200
//height = height of tile in pixels, for minimal memory usage try 200
//saveFileLocation = folder to save image tiles
//component = The JComponent to save as tiles
public static boolean saveComponentTiles(int width, int height, String saveFileLocation, JComponent component)
{   
    try
    {
        //Calculate tile sizes
        int componentWidth = component.getWidth();
        int componentHeight = component.getHeight();
        int horizontalTiles = (int) Math.ceil((double)componentWidth / width); //use (double) so Math.ceil works correctly.
        int verticalTiles = (int) Math.ceil((double)componentHeight / height); //use (double) so Math.ceil works correctly.
        System.out.println("Tiles Required (H, W): "+horizontalTiles+", verticalTiles: "+verticalTiles);

        //preset arguments
        BufferedImage image;

        //Loop through vertical and horizontal tiles
        //Draw part of the component to the image
        //Save image to file
        for (int h = 0; h < verticalTiles; h++)
        {
        for (int w = 0; w < horizontalTiles; w++)
        {
            //check tile size, if area to paint is smaller than image then shrink image
            int imageHeight = height;
            int imageWidth = width;
            if (h + 1 == verticalTiles)
            {
            imageHeight = componentHeight - (h * height);
            }
            if (w + 1 == horizontalTiles)
            {
            imageWidth = componentWidth - (w * width);
            }
            image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_ARGB);
            Graphics g = image.getGraphics();

            //translate image graphics so that only the correct part of the component is panted to the image
            g.translate(-(w * width), -(h * height));
            component.paint(g);

            //In my example I am saving the image to file, however you could throw your PDF processing code here
            //Files are named as "Image.[h].[w]"
            //Example: Image 8 down and 2 accross would save as "Image.8.2.png"
            ImageIO.write(image, "png", new File(saveFileLocation + "Image." + h +"."+ w + ".png"));
            //tidy up
            g.dispose();
        }
        }
        return true;
    }
    catch (IOException ex)
    {
        return false;
    }
}
另外,如果您还没有这样做,您应该只从调用方法,因为它将在处理大型组件时挂起您的应用程序

如果您还没有选择PDF库,那么我强烈建议您查看

原职:

您正在寻找的过程非常简单,但可能需要一些工作

你对零件的思考是对的,但是作为大卫 提到您不应该弄乱jTable,相反,您需要一个 使用TileImage类,或者自己做一些事情 渲染图像和光栅

这种方法基本上使用HDD空间,而不是内存和内存 允许您在许多较小的部分/平铺中创建大型图像,然后 完成后,您可以将其全部保存到单个图像文件中

这个答案也有助于:


使用-Xmx=2048M作为java命令的参数添加更多内存。我不应该增加堆内存,我正在寻找将jtable切片为小尺寸图像,然后将其保存在pdf图像中的想法。有可能吗?也许你应该改变你的问题标题,以反映你想要达到的目标。我想到的一件事是,如果你把JTable分解成几块,每一块可能会有不同的列大小,例如,这里有一种使用nio-mappedbytebuffer的方法。你可以尝试的另一件事是,使用并打印成PDF。但是,下面是另一行:你真的需要将其保存为PDF或图像吗?为什么不尝试将数据保存为电子表格/CSV文件?它将解决您的内存问题,并且仍然以易于使用的格式保存所有信息。我正在寻找一种机制,可以将Jtable拆分为不同的小图像,然后将这些小图像附加到PDF文件中。有没有办法将一个表拆分成不同的图像?@user3201343看到我更新的答案,我相信这就是你想要实现的?不,这不是一个简单的表,它就像一个显示统计数据的图像,我使用了渲染器来显示统计数据。因此,当用户希望保存查看的统计信息时,在看到统计信息后,他们应该能够保存它,这就是我的要求。如果表格太大,当用户单击“保存”按钮时,我遇到了问题。@user3201343抱歉,我不明白您的意思。您需要一种机制将Jtable拆分为不同的小图像,这正是我的代码所做的,只需将任何Jtable或JComponent传递给它即可。在我的示例中,我在创建JTable时将其每个imagepart保存到文件中,从而将整个JTable以片段的形式保存到文件中。您需要修改代码的最后一部分,将每个图像直接附加到PDF中,而不是将每个图像保存到文件中。
boolean result = saveComponentTiles(200, 200, saveFileLocation, jTable1);