6

Under Java what is the best way to go about converting an TIF file to a PNG?

Simplicity is preferable, but if the simplest way is to use a third party library then I would consider that solution.

James McMahon
  • 48,506
  • 64
  • 207
  • 283

5 Answers5

10

First, install JAI. Then install JAI/ImageIO. Then do

public static void main(final String[] args) throws Exception
{
    final BufferedImage tif = ImageIO.read(new File("test.tif"));
    ImageIO.write(tif, "png", new File("test.png"));
}
Jonathan Feinberg
  • 44,698
  • 7
  • 80
  • 103
  • Can you explain what is going on with the non-standard install? Usually Java libraries are just JAR files that you place inside your CLASSPATH, but JAI installs native DLLs as well. How does this work if you deploy to a webserver? – James McMahon Feb 18 '10 at 19:17
  • 2
    You can also get pure-java JAI, but there's no reason to do so, if your platform is supported by the native code. If you deploy your app to a web server, then the server's JRE must also have the JAI and JAI/ImageIO extensions installed as well. – Jonathan Feinberg Feb 18 '10 at 19:19
  • @Jonathan Feinberg, Do you need to include the JARs on the classpath or does installing the extensions make it part of the JRE? – James McMahon Feb 18 '10 at 19:22
  • The installers do everything required to make it "just work" with your JRE. – Jonathan Feinberg Feb 18 '10 at 19:29
  • @Jonathan Feinberg, I am having no luck with this approach; the ImageIO.read() call is returning null. Any suggestions? – James McMahon Feb 18 '10 at 20:04
  • I should also note that I am using the approach laid out at http://www.exampledepot.com/egs/javax.imageio/DetermineFormat.html to check to see if TIF files are supported for read operations, according to canReadFormat(), they are not. – James McMahon Feb 18 '10 at 20:07
  • Right. First you have to install JAI and JAI/ImageIO. – Jonathan Feinberg Feb 18 '10 at 20:39
  • @Jonathan Feinberg, yeah I installed both of those, I've ever tried copying the DLLs manually into various JDK and JREs I have installed on my system. I am having no luck. – James McMahon Feb 19 '10 at 12:25
  • Once I include the JAI and JAI ImageIO JARs in my path it seems to be working. I think this may bypass the DLLs and make native Java calls, which may be less preformant. – James McMahon Feb 19 '10 at 12:29
  • This site has some good tips to see if JAI is installed properly programmatically http://forums.java.net/jive/message.jspa?messageID=64311. – James McMahon Feb 19 '10 at 20:08
  • Full and simple answer!! After searching and trying out 5-6 different codes for the last 10 hours, this simple little code solved my problem. <3 – elcool Aug 31 '11 at 20:34
  • 1
    Sorry to bother you guys, but where are the download links for JAI and JAI/ImageIO?? – Marsellus Wallace Sep 16 '11 at 20:57
  • @Jonathan Feinberg what about multi tiff – Mahmoud Saleh May 27 '18 at 19:29
7

Use imageMagic java libraries like im4java, their performance and quality is much better then JAI

for example:

import org.im4java.core.ConvertCmd;
import org.im4java.core.IMOperation;

public static void convertTifToPng(File inputImage, File outputImage){
  IMOperation op = new IMOperation();
  op.addImage(); //place holder for input file
  op.addImage(); //place holder for output file

  ConvertCmd convert = new ConvertCmd();
  convert.run(op, new Object[]{inputImage.getAbsolutePath(), outputImage.getAbsolutePath()});
}

maven dependency for im4java is

<dependency>
  <groupId>im4java</groupId>
  <artifactId>im4java</artifactId>
  <version>0.98.0</version>
</dependency>
James McMahon
  • 48,506
  • 64
  • 207
  • 283
giladbu
  • 2,839
  • 2
  • 19
  • 14
  • 1
    I agree that IM's quality is excellent, but I would be very nervous about using it in-process like that (because, in my opinion, the engineering quality is not good, and there can be fatal crashes). I'd instead shell-out to `convert` using ProcessBuilder, if I were going to use IM. – Jonathan Feinberg Feb 18 '10 at 19:21
  • 1
    @giladbu: ImageMagick is great and I do it the way Jonathan is suggesting but I just want to comment on the "quality" part: I very much doubt that JAI would produce an image of worse quality than ImageMagick when *reading* a lossy TIFF (should the TIFF of the OP be lossy). As for PNG, it's lossless and JAI cannot go wrong there. So in the TIFF-to-PNG case I don't agree that ImageMagick's quality would be better than JAI. For TIFF-to-JPG now we'd be talking about something entirely different and I'd use ImageMagick without thinking twice about it. – SyntaxT3rr0r Feb 18 '10 at 20:12
  • Hmm I didn't realize that PNGs were lossless. – James McMahon Feb 19 '10 at 12:45
  • So what does the ImageMagic approach require? An installation of the ImageMagic command line tools and then plugging the im4java jars into my project? – James McMahon Feb 19 '10 at 12:53
  • 1
    im4java does shell-out to convert using ProcessBuilder. – Jeffrey Knight Nov 15 '10 at 20:45
1

Java advanced imaging APi is a good library for image manipulations

http://java.sun.com/products/java-media/jai/iio.html

MLefrancois
  • 768
  • 5
  • 12
  • Yeah I was looking at that, I honestly have no idea how to install it. They have a download ZIP that contains a JAR file with an EXE file inside of it. I've never seen that before. – James McMahon Feb 18 '10 at 19:06
1

Download JIMI Software Development Kit jimi1_0.zip and set JimiProClasses.zip to your classpath

http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-java-client-419417.html#7259-jimi_sdk-1.0-oth-JPR

JIMI is older java image library, but it is easy to use and there is no platform dependent code (no native executables, can use it like standard jar)

import java.awt.Image;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

import com.sun.jimi.core.Jimi;

public class JIMIImageConverter {

public static byte[] convert(byte[] inBytes, String inMimeType, String outMimeType) throws Exception{

    Image rawImage = Jimi.getImage(new ByteArrayInputStream(inBytes), inMimeType);
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    Jimi.putImage(outMimeType, rawImage, outputStream);
    return outputStream.toByteArray();

}

}

where inMimeType and outMimeType are graphics formats mimetypes

wsx22
  • 11
  • 1
0

maybe you can use this code, works for me

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.awt.image.renderable.ParameterBlock;
import java.io.File;
import java.io.IOException;

import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;

import com.sun.media.jai.codec.FileSeekableStream;
import com.sun.media.jai.codec.ImageCodec;
import com.sun.media.jai.codec.ImageDecoder;
import com.sun.media.jai.codec.SeekableStream;

public class ImageConvert {

    public static RenderedImage[] readMultiPageTiff(String fileName)throws IOException{
           File file = new File(fileName);
           SeekableStream seekableStream = new FileSeekableStream(file);
           ImageDecoder decoder = ImageCodec.createImageDecoder("tiff", seekableStream, null);
           int numPages = decoder.getNumPages();
           RenderedImage image[]= new RenderedImage[numPages];
           int count = 0;
           for(int i=0;i<decoder.getNumPages();i++){
               image[i] = decoder.decodeAsRenderedImage(i);
               count++;
           }

           String newFolderName;
           String s3 = fileName;
           String [] temp = null;
           temp = s3.split("\\.");


           int j;
               j = 0;
               do{
                     newFolderName = temp[j];
                     String spoonFeeding = newFolderName;
                     File f = new File(spoonFeeding);
                     f.mkdirs();
                     j++;
               }while (j<1);

           for (int i = 0; i < count; i++) {
               RenderedImage page = decoder.decodeAsRenderedImage(i);
               File fileObj = new File(newFolderName+"/" + (i+1) + ".png");
               System.out.println("Saving " + fileObj.getCanonicalPath());
               ParameterBlock parBlock = new ParameterBlock();
               parBlock.addSource(page);
               parBlock.add(fileObj.toString());
               parBlock.add("png");
               RenderedOp renderedOp = JAI.create("filestore",parBlock);
               renderedOp.dispose();
           }
           return image;
        }

}
hardcess
  • 1
  • 1