Java 使用低内存占用或恒定内存占用连接多个jpeg图像

Java 使用低内存占用或恒定内存占用连接多个jpeg图像,java,jpeg,javax.imageio,Java,Jpeg,Javax.imageio,我有多个图像,每个图像的分辨率约为2560x10000,我想将所有这些图像合并成一个图像。我不能使用BuffereImage方法作为最终图像,我必须加入的图像将同时在内存中,从而导致OutOfMemory。因此,我尝试了以下方法: public static void joinJpegFiles(File infile, File outfile, float compQuality,int i) { try { RenderedImage renderedImage =

我有多个图像,每个图像的分辨率约为2560x10000,我想将所有这些图像合并成一个图像。我不能使用BuffereImage方法作为最终图像,我必须加入的图像将同时在内存中,从而导致OutOfMemory。因此,我尝试了以下方法:

public static void joinJpegFiles(File infile, File outfile, float compQuality,int i) {
    try {
        RenderedImage renderedImage = ImageIO.read(infile);
        ImageWriter Iwriter = null;

        Iterator iter = ImageIO.getImageWritersByFormatName("jpeg");
        if (iter.hasNext()) {
            Iwriter = (ImageWriter)iter.next();
        }

        ImageOutputStream IOStream = ImageIO.createImageOutputStream(outfile);
        Iwriter.setOutput(IOStream);
        IOStream.seek( IOStream.length());
        JPEGImageWriteParam JIWP=new JPEGImageWriteParam(Locale.getDefault());
        JIWP.setCompressionMode(ImageWriteParam.MODE_EXPLICIT) ;
        JIWP.setCompressionQuality(compQuality);
        Iwriter.write(null, new IIOImage(renderedImage,null,null), JIWP);               
        IOStream.flush();
        IOStream.close();
        Iwriter.dispose();
    } catch (IOException e) {
        System.out.println("write error: " + e.getMessage());
    }
}
对于我要加入的每个图像,都会调用此方法。
这种方法的问题是,最终图像的大小正在增加,等于我加入的所有图像的大小之和,但当我打开最终图像时,只有第一个图像可见。
我仍然不知道我做错了什么,除了BuffereImage和ImageIO.write方法之外,我也找不到任何加入JPEG的示例代码。我在一个新闻组读到,它适用于tiff格式,但我需要它来适用于jpeg/png格式。

我想你已经解决了这个问题,或者以某种方式解决了这个问题,但是。。如果其他任何人需要解决类似问题:

有点不清楚你在这里想要实现什么。您真的要创建一个大图像,还是创建一个包含多个图像的文件

单个文件中有多个图像:

您的代码似乎将多个独立的JPEG文件附加到一个文件中。JPEG(JFIF)格式不支持这一点,大多数软件可能只会将您的文件视为第一个JPEG,并在其末尾附加大量垃圾字节。PNG不允许在一个文件AFAIK中存储多个图像。像TIFF这样的格式确实允许多个图像(它甚至允许您将它们存储为JPEG流),这可能就是TIFF被提出的原因

然而,JPEG标准有一个称为的概念,这与JPEG通常存储在金字塔TIFF中的方式非常相似。ImageIO
JPEGImageWriter
不支持此功能:

缩写流是使用ImageWriter的顺序方法编写的。流元数据用于在流的开头写入仅表的映像,并且使用ImageWriter.prepareWriteSequence设置表以供使用。如果未向ImageWriter.prepareWriteSequence提供流元数据,则不会写入任何表,仅写入图像。如果向ImageWriter.prepareWriteSequence提供了不包含表的流元数据,则会写入包含默认视觉无损表的仅表图像。“

我不确定其他软件将如何解释这些类型的文件,根据它的说法,这些文件甚至可能无法工作:

“而缩写的数据流 在封闭环境中可能很有用,因此强烈建议不要使用 可能需要与其他应用程序进行数据交换的任何情况。 警告设计师。”

因此,它可能适合您的用例,也可能不适合您的用例

将多个图像合成为一个大图像:

另一方面,如果您真的想将多个图像合成为一个大图像(稍后存储为一个JPEG),您可以看看我很久以前写的,以允许在不使用堆内存的情况下处理大图像


它会使用,如果您没有足够的内存将数据存储在RAM中,它的速度可能会非常慢。此外,生成的
buffereImage
将始终是
TYPE_CUSTOM
,因此它将错过您通常会受益的大多数潜在硬件或本机加速,并且某些操作可能无法对其进行操作。但是,至少您可以e不受堆大小和物理RAM的限制。

仅供参考,我还使用了Iwriter.write(-1,new IIOImage(renderImage,null,null),JIWP);但这会引发不受支持的变体异常。你解决过这个问题吗?有点晚了,但我已经完成了,有这个问题的人至少应该尝试一下。