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

时间:2011-07-12 17:00:02

标签: java tiff jai

我正在尝试将多个多页.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);
        }
    }

1 个答案:

答案 0 :(得分:7)

我知道我只是遗漏了一些关于迭代单个.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);
        }
    }