Java OutOfMemoryError:jtable另存为映像时占用堆空间
目前,我正在使用以下方法将jtable保存为jpeg,当jtable的维度变为2590126181,java.lang.OutOfMemoryError:BuffereImage构造函数发生java堆空间异常,当表的大小较小时,图像成功保存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
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);