Не удается прочитать и записать файл изображения TIFF с помощью стандартной библиотеки Java ImageIO

Я не знаю, что делать с изображениями TIFF, но я не могу прочитать или записать ни одно из них, используя обычную стандартную библиотеку ImageIO Java. Есть предположения?

Спасибо.


person Gle    schedule 23.12.2009    source источник
comment
Вы используете Java SE? Java Advanced Imaging API поддерживает TIFF. Подробности здесь.   -  person MPG    schedule 23.12.2009
comment
Вам понадобится пакет JAI для работы с файлами TIFF. Простой пример отображения файла TIFF: Отображение TIF   -  person RealHowTo    schedule 24.12.2009
comment
Была та же проблема, добавив JAI jar в мой путь к классам, это решило. Не нужно ничего менять в вашем коде и не нужно добавлять JAI во время компиляции. Просто добавьте его во время выполнения, и ImageIO.getImageReaders сможет найти его самостоятельно, поскольку он сканирует путь к классам в поисках читателей.   -  person SomethingSomething    schedule 14.03.2018


Ответы (5)


Если вам не нравится или вы не можете использовать JAI по какой-либо причине, я написал плагин TIFF ImageReader для ImageIO, доступный на GitHub. Это чистая Java, не требующая собственных установок и идущая с очень удобной лицензией с открытым исходным кодом (BSD).

Он поддерживает любой базовый вариант TIFF, а также множество стандартных расширений. Начиная с версии 3.1 плагин TIFF также поддерживает запись.

С правильными JAR-файлами в пути к классам использование может быть таким же простым, как:

BufferedImage image = ImageIO.read(inputTIFF);
// ...modify image (compose, resize, sharpen, etc)...
ImageIO.write(image, "TIFF", outputTIFF);
person Harald K    schedule 29.05.2013
comment
Привет, haraldK, как ты этим пользуешься ??? Мне вообще не нравится JAI, я не нашел ни одного примера, как конвертировать tiff-файл в jpg. Я пробовал: BufferedImage image = ImageIO.read (новый файл (inFile)); ! ImageIO.write (изображение, jpg, новый файл (outFile))) - person delkant; 08.04.2014
comment
@delkant Это могло бы сработать, если бы у вас все было правильно установлено. Дополнительную информацию см. В инструкции по установке или сообщите о проблеме (с полной информацией), если вы не могу заставить его работать. - person Harald K; 08.04.2014

Согласно JEP 262: TIFF Image I / O плагин TIFF, который раньше был частью JAI, будет быть доступным как часть Java SE, начиная с Java 9.

Это означает, что при использовании Java 9 или более поздней версии следующий код будет работать без каких-либо дополнительных операций импорта или зависимостей:

BufferedImage image = ImageIO.read(inputTIFF);
// ...modify image (compose, resize, sharpen, etc)...
ImageIO.write(image, "TIFF", outputTIFF);

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

person Harald K    schedule 22.11.2016

Я попробовал JAI, и у меня это не сработало.

Где ты застрял? Следующее работает для вас?

import java.io.File;
import java.io.FileOutputStream;
import java.awt.image.RenderedImage;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import javax.media.jai.NullOpImage;
import javax.media.jai.OpImage;
import com.sun.media.jai.codec.SeekableStream;
import com.sun.media.jai.codec.FileSeekableStream;
import com.sun.media.jai.codec.TIFFDecodeParam;
import com.sun.media.jai.codec.ImageDecoder;
import com.sun.media.jai.codec.ImageCodec;

public class Main {
    public static void main(String args[]) {
        File file = new File("input.tif");
        try {
            SeekableStream s = new FileSeekableStream(file);
            TIFFDecodeParam param = null;
            ImageDecoder dec = ImageCodec.createImageDecoder("tiff", s, param);
            RenderedImage op = new NullOpImage(dec.decodeAsRenderedImage(0),
                                               null,
                                               OpImage.OP_IO_BOUND,
                                               null);
            FileOutputStream fos = new FileOutputStream("output.jpg");
            JPEGImageEncoder jpeg = JPEGCodec.createJPEGEncoder(fos);
            jpeg.encode(op.getData());
            fos.close();
        }
        catch (java.io.IOException ioe) {
            System.out.println(ioe);
        } 
    }
}
person MPG    schedule 24.12.2009
comment
Если у вас есть jai_imageio.jar в пути к классам, вы просто сможете использовать ImageIO API как обычно. - person MadProgrammer; 18.07.2012
comment
какая это версия банки и в каком репозитории она хранится? Я поискал в Maven и не нашел. - person SoftwareSavant; 11.05.2018

Java поддерживает формат TIFF только начиная с версии Java 9. Если вы пытаетесь использовать ImageIO для TIFF в более старой версии Java, это вызовет исключение.

Если вы хотите использовать TIFF и в более ранней версии, вы можете использовать плагин Twelve Monkey вместе с Java, просто добавив зависимость от Twelve Monkey.

Зависимость Maven для двенадцати обезьян:

<dependency>
   <groupId>com.twelvemonkeys.imageio</groupId>
   <artifactId>imageio-tiff</artifactId>
   <version>3.5</version>
</dependency>*

Я также привожу пример объединения нескольких изображений в один TIFF со страницами, использующими Twelve Monkey,

BufferedImage b1 = null;
BufferedImage b2 = null;

TIFFImageReaderSpi SPI = new TIFFImageReaderSpi();

ImageReader imageReader1 = SPI.createReaderInstance();
ImageInputStream iis1 = ImageIO.createImageInputStream(new File("1.tif"));
imageReader1.setInput(iis1);
b1 = imageReader1.read(0); 

ImageReader imageReader2 = SPI.createReaderInstance();
ImageInputStream iis2 = ImageIO.createImageInputStream(new File("2.tif"));
imageReader2.setInput(iis2);
b2 = imageReader2.read(0);

ImageWriter writer = ImageIO.getImageWritersByFormatName("TIFF").next();

writer.setOutput(ImageIO.createImageOutputStream(new File("3.tif")));

ImageWriteParam writeParam = writer.getDefaultWriteParam();
//writeParam.setTilingMode(ImageWriteParam.MODE_EXPLICIT);
//writeParam.setCompressionType("Deflate");

writer.prepareWriteSequence(null);

IIOImage i1 = new IIOImage(b1, null, null);
IIOImage i2 = new IIOImage(b2, null, null);

writer.writeToSequence(i1, writeParam);
writer.writeToSequence(i2, writeParam);

writer.endWriteSequence();
writer.dispose();

Приведенный выше код будет работать с Java8 и написан для открытия двух изображений TIFF и объединения их в один.

Кроме того, при необходимости вы можете использовать сжатие. Просто используйте строки комментариев, чтобы добавить сжатие.

person Sandeep Kumar    schedule 01.06.2020

Добавить зависимость Maven:

<dependency>
  <groupId>org.geotoolkit</groupId>
  <artifactId>geotk-coverageio</artifactId>
  <version>3.17</version>
</dependency>

Пример кода:

import org.geotoolkit.image.io.plugin.RawTiffImageReader;

IIORegistry registry = IIORegistry.getDefaultInstance();   
registry.registerServiceProvider(new RawTiffImageReader.Spi());            

String[] a = ImageIO.getReaderFileSuffixes();    
for (int i=0; i<a.length; i++) {
 System.out.println(a[i]);
}   

BufferedImage image = ImageIO.read(new File("C:\\mypic.tiff"));

ImageIO.write(image, "jpg",new File("C:\\out.jpg"));
ImageIO.write(image, "gif",new File("C:\\out.gif"));
ImageIO.write(image, "png",new File("C:\\out.png"));
ImageIO.write(image, "tif",new File("C:\\out.tiff"));
person Miguelin    schedule 01.08.2012
comment
Боюсь, что зависимость больше не работает. Что сработало для меня: ‹dependency› ‹groupId› com.github.jai-imageio ‹/groupId› ‹artifactId› jai-imageio-core ‹/artifactId› ‹version› 1.3.1 ‹/version› ‹/dependency› (Я не пробовал со всем вашим кодом). - person DarkPurpleShadow; 18.07.2017