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

发布于 2024-11-19 19:36:29 字数 2019 浏览 1 评论 0原文

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

我在这个 问题,但它似乎只获取每个单独 .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);
        }
    }

I am trying to take multiple multi-page .tif files and combine them into a single multi-page tif file.

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.

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?

To clarify, I would like the source files:

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

to be combined into

  • combined.tif (8 pages)

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.

The code from the referenced question, modified by me to load all the .tif files in a directory, is below for easy answering:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

海之角 2024-11-26 19:36:29

我知道我只是错过了有关在单个 .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);
        }
    }

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.

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. 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:

params.setExtraImages(imageList.iterator());

which keeps the first page out of the "ExtraImages" and it gets added with the call to encode.

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);
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文