Java 我可以保存一个巨大的PNG而不把整个东西都存储在内存中吗?

Java 我可以保存一个巨大的PNG而不把整个东西都存储在内存中吗?,java,png,Java,Png,我用Java保存了一个非常大的PNG(25MB左右)。问题是,当它被生成时,它使用了3+千兆字节的内存,这并不理想,因为它严重降低了内存不足的系统的速度 我正在使用的代码需要将一组平铺图像组合成一个图像;换句话说,我有九幅图像(PNG): 有没有一种方法可以在不将整个图像存储在内存中的情况下制作和保存图像 编辑: 为了绘制图像,我在循环中执行以下操作: BufferedImage tile=ImageIO.read(新文件(“File.png”); g2d.绘图图像(瓷砖,x,y,w,h);

我用Java保存了一个非常大的PNG(25MB左右)。问题是,当它被生成时,它使用了3+千兆字节的内存,这并不理想,因为它严重降低了内存不足的系统的速度

我正在使用的代码需要将一组平铺图像组合成一个图像;换句话说,我有九幅图像(PNG):

有没有一种方法可以在不将整个图像存储在内存中的情况下制作和保存图像


编辑: 为了绘制图像,我在循环中执行以下操作:

BufferedImage tile=ImageIO.read(新文件(“File.png”);
g2d.绘图图像(瓷砖,x,y,w,h);

这被重复了很多次(通常是25x25,但有时更多),因此,如果这里有一个小内存泄漏,这可能会导致问题。

ImageIO.write(图像,“png”,文件)
在内部使用com.sun.imageio.plugins.png.PNGImageWriter。该方法和该编写器希望图像是渲染图像,但PNG写入是由“bands”完成的,因此您可以创建RenderImage的子类,在编写器向图像请求波段时生成合成大图像的请求波段

从PNGImageWriter类:

private void encodePass(ImageOutputStream os,
                        RenderedImage image,
                        int xOffset, int yOffset,
                        int xSkip, int ySkip) throws IOException {
    // (...)
    for (int row = minY + yOffset; row < minY + height; row += ySkip) {
                Rectangle rect = new Rectangle(minX, row, width, 1); // <--- *1
                Raster ras = image.getData(rect); // <--- *2
private void encodePass(ImageOutputStream操作系统,
渲染图像,
int xOffset,int yOffset,
int xSkip,int ySkip)引发IOException{
// (...)
对于(int row=minY+yOffset;row矩形rect=新矩形(minX,row,width,1);//使用外部工具是一种选择吗?我记得出于类似目的使用ImageMagick,您需要先保存较小的图像。

您也可以查看此库(免责声明:我对其进行了编码),它允许逐行保存PNG图像。

你能提供如何绘制9幅图像中的一幅的代码吗?这可能是内存消耗的地方。我已将其添加到原始帖子的末尾。谢谢!这9幅图像和生成的图像的尺寸是什么?要缝合在一起的图像(实际上有几百个,通常约为25x25个图像)每个图像的大小为500x500px。生成的图像大小约为10000x1000px。请将ImageMagick与JMagick一起使用。指向上述内容的URL:
image = new BufferedImage(width, height, height, BufferedImage.TYPE_INT_ARGB_PRE);
g2d = image.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);

// draw the 9 images on here at their proper positions...

// save image
g2d.dispose();
File file = getOutputFile();
ImageIO.write(image, "png", file);
BufferedImage tile = ImageIO.read(new File("file.png"));
g2d.drawImage(tile, x, y, w, h);
private void encodePass(ImageOutputStream os,
                        RenderedImage image,
                        int xOffset, int yOffset,
                        int xSkip, int ySkip) throws IOException {
    // (...)
    for (int row = minY + yOffset; row < minY + height; row += ySkip) {
                Rectangle rect = new Rectangle(minX, row, width, 1); // <--- *1
                Raster ras = image.getData(rect); // <--- *2