简体   繁体   English

如何将多个多页 tif 文件合并为一个 tif

[英]How to combine multiple multi-page tif files into a single tif

I am trying to take multiple multi-page.tif files and combine them into a single multi-page tif file.我正在尝试获取多个 multi-page.tif 文件并将它们组合成一个多页 tif 文件。

I found some code in this question , but it only seems to take the first page of each individual.tif file and create the new multi-page.tif with those first pages.我在这个问题中找到了一些代码,但它似乎只获取每个 individual.tif 文件的第一页并使用这些第一页创建新的 multi-page.tif。

Is there a small change I'm not seeing that would cause this same code to grab every page from the source.tif files and put them all into the combined.tif?是否有一个我没有看到的小变化会导致相同的代码从 source.tif 文件中获取每一页并将它们全部放入 combine.tif?

To clarify, I would like the source files:为了澄清,我想要源文件:

  • SourceA.tif (3 pages) SourceA.tif (3 页)
  • SourceB.tif (4 pages) SourceB.tif (4 页)
  • SourceC.tif (1 page) SourceC.tif (1 页)

to be combined into被组合成

  • combined.tif (8 pages)组合.tif (8 页)

I would also like to be able to specify a resolution and compression of the.tif, but I'm not sure if JAI supports that and it's not a necessity for a correct answer.我还希望能够指定.tif 的分辨率和压缩,但我不确定 JAI 是否支持它,并且它不是正确答案的必要条件。

The code from the referenced question, modified by me to load all the.tif files in a directory, is below for easy answering:下面是引用问题的代码,由我修改以加载目录中的所有 .tif 文件,以便于回答:

public static void main(String[] args) {
        String inputDir = "C:\\tifSources";
        File sourceDirectory = new File(inputDir);
        File file[] = sourceDirectory.listFiles();
        int numImages = file.length;

        BufferedImage image[] = new BufferedImage[numImages];

        try
        {
            for (int i = 0; i < numImages; i++)
            {
                SeekableStream ss = new FileSeekableStream(file[i]);
                ImageDecoder decoder = ImageCodec.createImageDecoder("tiff", ss, null);
                PlanarImage op = new NullOpImage(decoder.decodeAsRenderedImage(0), null, null, OpImage.OP_IO_BOUND);
                image[i] = op.getAsBufferedImage();
            }

            TIFFEncodeParam params = new TIFFEncodeParam();
            OutputStream out = new FileOutputStream(inputDir + "\\combined.tif"); 
            ImageEncoder encoder = ImageCodec.createImageEncoder("tiff", out, params);
            List<BufferedImage> imageList = new ArrayList<BufferedImage>();   
            for (int i = 0; i < numImages; i++)
            {
                imageList.add(image[i]); 
            }
            params.setExtraImages(imageList.iterator()); 
            encoder.encode(image[0]); 
            out.close();
        }
        catch (Exception e)
        {
            System.out.println("Exception " + e);
        }
    }

I knew I was just missing some little part about iterating over the pages in a single.tif, I just wasn't sure where it was.我知道我只是遗漏了一些关于在 single.tif 中迭代页面的小部分,我只是不确定它在哪里。

More searching on the internet led me to find that rather than doing:在互联网上进行更多搜索使我发现而不是这样做:

PlanarImage op = new NullOpImage(decoder.decodeAsRenderedImage(0), null, null, OpImage.OP_IO_BOUND);

I wanted to iterate over every page in the current document with something like:我想遍历当前文档中的每一页,例如:

int numPages = decoder.getNumPages();
for(int j = 0; j < numPages; j++)
{
     PlanarImage op = new NullOpImage(decoder.decodeAsRenderedImage(j), null, null, OpImage.OP_IO_BOUND);
     images.add(op.getAsBufferedImage());
}

This adds every page of every.tif into the images List.这会将every.tif 的每一页添加到图像列表中。 One final trap was that the final call to最后一个陷阱是对

encoder.encode(images.get(0));

Would cause the first page to be in the new.tif twice, so I added an intermediate loop and List population that doesn't add the first page in the call to:会导致第一页两次出现在 new.tif 中,所以我添加了一个中间循环和列表填充,它不会在调用中添加第一页:

params.setExtraImages(imageList.iterator());

which keeps the first page out of the "ExtraImages" and it gets added with the call to encode.它将第一页保留在“ExtraImages”之外,并与编码调用一起添加。

Final updated code is:最终更新的代码是:

public static void main(String[] args) {
        String inputDir = "C:\\tifSources";
        File faxSource = new File(inputDir);
        File file[] = faxSource.listFiles();
        System.out.println("files are " + Arrays.toString(file));
        int numImages = file.length;

        List<BufferedImage> images = new ArrayList<BufferedImage>();

        try
        {
            for (int i = 0; i < numImages; i++)
            {
                SeekableStream ss = new FileSeekableStream(file[i]);
                ImageDecoder decoder = ImageCodec.createImageDecoder("tiff", ss, null);

                int numPages = decoder.getNumPages();
                for(int j = 0; j < numPages; j++)
                {
                    PlanarImage op = new NullOpImage(decoder.decodeAsRenderedImage(j), null, null, OpImage.OP_IO_BOUND);
                    images.add(op.getAsBufferedImage());
                }
            }

            TIFFEncodeParam params = new TIFFEncodeParam();
            OutputStream out = new FileOutputStream(inputDir + "\\combined.tif"); 
            ImageEncoder encoder = ImageCodec.createImageEncoder("tiff", out, params);
            List<BufferedImage> imageList = new ArrayList<BufferedImage>();   
            for (int i = 1; i < images.size(); i++)
            {
                imageList.add(images.get(i)); 
            }
            params.setExtraImages(imageList.iterator()); 
            encoder.encode(images.get(0));
            out.close();
        }
        catch (Exception e)
        {
            System.out.println("Exception " + e);
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM