27

I don't know what to do with TIFF images, but I can't read or write any of them using straight Java standard ImageIO library. Any thoughts?

Thanks.

Gle
  • 281
  • 1
  • 3
  • 4
  • 2
    Are you using Java SE? The [Java Advanced Imaging API](http://java.sun.com/products/java-media/jai/iio.html) supports TIFF. Details [here](https://jai-imageio.dev.java.net/). – MPG Dec 23 '09 at 19:14
  • 3
    You need the [JAI package](https://jai.dev.java.net/#Downloads) to deal with TIFF files. A simple example to display a TIFF file : [Display a TIF](http://www.rgagnon.com/javadetails/java-0605.html) – RealHowTo Dec 23 '09 at 21:26
  • 2
    Had the same problem, adding JAI's jar to my classpath solved it. No need to change anything in your code and no need to add JAI at compilation time. Simply add it in runtime and `ImageIO.getImageReaders` will be able to find it on its own, as it scans the classpath, looking for readers. – SomethingSomething Mar 14 '18 at 11:14

5 Answers5

21

If you don't like or can't use JAI for any reason I have written a TIFF ImageReader plugin for ImageIO, available on GitHub. It is pure Java and does not need any native installs, and comes with a very friendly open source license (BSD).

It supports any baseline TIFF option, along with a lot of standard extensions. From version 3.1 the TIFF plugin also has write support.

With the proper JARs in your class path, usage can be as simple as:

BufferedImage image = ImageIO.read(inputTIFF);
// ...modify image (compose, resize, sharpen, etc)...
ImageIO.write(image, "TIFF", outputTIFF);
Harald K
  • 26,314
  • 7
  • 65
  • 111
  • HI haraldK how do you use this??? I don't like JAI at all, I couldn't find any example on how to convert a tiff file to jpg. I tried: BufferedImage image = ImageIO.read(new File(inFile)); !ImageIO.write(image, "jpg", new File(outFile))) – delkant Apr 07 '14 at 23:20
  • @delkant That could should work, if you have everything properly installed. Please see the [installation instructions](https://github.com/haraldk/TwelveMonkeys#installing) for further details, or file an issue (with full details) if you can't make it work. – Harald K Apr 08 '14 at 10:16
11

According to JEP 262: TIFF Image I/O the TIFF plugin that used to be part of JAI will be available as part of the Java SE, starting from Java 9.

That means, using Java 9 or later, the following code will just work, without any extra imports or dependencies:

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

I haven't yet been able to verify the support for non-baseline TIFF flavors in this plugin, but I assume at least baseline TIFFs should be fully supported.

Harald K
  • 26,314
  • 7
  • 65
  • 111
5

I tried JAI, and it didn't work for me.

Where are you stuck? Does the following work for you?

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);
        } 
    }
}
MPG
  • 835
  • 4
  • 10
1

Java supports TIFF format only from Java 9 release. If you are trying to use ImageIO for TIFF into older Java version it will give you exception.

If you want to use TIFF in earlier version as well, you Twelve Monkey plugin along with Java just by adding dependency of Twelve Monkey.

Maven Dependency for Twelve Monkey:

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

I'm also giving example to merge the multiple images into Single TIFF with pages using 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();

The above code will work with Java8 and written to open two TIFF image and merge into single.

Also, you may use compression as needed. Just use comment lines to add compression.

Sandeep Kumar
  • 596
  • 5
  • 7
-4

Add Maven dependency :

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

Code example :

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"));
Stephan
  • 41,764
  • 65
  • 238
  • 329
  • I'm afraid that dependency doesn't work anymore. What worked for me: com.github.jai-imageio jai-imageio-core 1.3.1 (I didn't try it out with the whole code of yours). – Purrrple Jul 18 '17 at 08:32