Как объединить несколько многостраничных файлов TIF в один TIF - PullRequest
3 голосов
/ 12 июля 2011

Я пытаюсь взять несколько многостраничных файлов .tif и объединить их в один многостраничный tif-файл.

Я нашел код в этом вопросе , но это толькокажется, берет первую страницу каждого отдельного файла .tif и создает новый многостраничный файл .tif с этими первыми страницами.

Есть ли небольшое изменение, которое я не вижу, из-за которого этот же код может быть захваченкаждую страницу из исходных файлов .tif и помещать их все в объединенный файл .tif?

. Чтобы уточнить, я хотел бы получить исходные файлы:

  • SourceA.tif (3 страницы)
  • SourceB.tif (4 страницы)
  • SourceC.tif (1 страница)

для объединения в

  • вместе.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 Ответ

7 голосов
/ 13 июля 2011

Я знал, что просто упускаю какую-то небольшую часть про итерации по страницам в одном .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);
        }
    }
...