【问题标题】:How to combine multiple multi-page tif files into a single tif如何将多个多页 tiff 文件合并为一个 tif
【发布时间】:2011-07-12 17:00:02
【问题描述】:

我正在尝试获取多个多页 .tif 文件并将它们组合成一个多页 tif 文件。

我在 question 中找到了一些代码,但它似乎只获取每个单独 .tif 文件的第一页并使用这些第一页创建新的多页 .tif。

是否有一个我没有看到的小变化会导致相同的代码从源 .tif 文件中抓取每一页并将它们全部放入组合的 .tif 中?

为了澄清,我想要源文件:

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

合并成

  • combined.tif(8 页)

我还希望能够指定 .tif 的分辨率和压缩率,但我不确定 JAI 是否支持这一点,并且这不是正确答案的必要条件。

为了方便回答,我修改了引用问题中的代码以加载目录中的所有 .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);
        }
    }

【问题讨论】:

    标签: java tiff jai


    【解决方案1】:

    我知道我只是遗漏了一些关于在单个 .tif 中迭代页面的小部分,我只是不确定它在哪里。

    在互联网上进行更多搜索使我发现而不是这样做:

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

    我想遍历当前文档中的每一页,例如:

    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());
    }
    

    这会将每个 .tif 的每一页添加到图像列表中。最后一个陷阱是对

    的最后调用
    encoder.encode(images.get(0));
    

    会导致第一页两次出现在新的 .tif 中,所以我添加了一个中间循环和列表填充,它不会在调用中添加第一页:

    params.setExtraImages(imageList.iterator());
    

    将第一页排除在“ExtraImages”之外,并通过对编码的调用添加。

    最终更新代码为:

    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);
            }
        }
    

    【讨论】:

    • 应该有一种无需解码过程即可组合 TIFF 的方法
    • 好的,在向现有的 TIFFTweaker 添加新方法后,我能够将任意数量的多页 TIFF 合并为一个,而无需实际解码任何一个,现在它是这个 Java 库的一部分 - github.com /dragon66/icafe/wiki
    • 谢谢哥们!!
    猜你喜欢
    • 2012-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-17
    • 2019-06-14
    • 1970-01-01
    • 2015-08-17
    • 2011-07-30
    相关资源
    最近更新 更多