15

I tried the following code to accomplish the task of reading and writing tiff images:

 // Define the source and destination file names.
 String inputFile = /images/FarmHouse.tif
 String outputFile = /images/FarmHouse.bmp

 // Load the input image.
 RenderedOp src = JAI.create("fileload", inputFile);

 // Encode the file as a BMP image.
 FileOutputStream stream =
     new FileOutputStream(outputFile);
 JAI.create("encode", src, stream, BMP, null);

 // Store the image in the BMP format.
 JAI.create("filestore", src, outputFile, BMP, null);

However, when I run the code, I get the following error message:

Caused by: java.lang.IllegalArgumentException: Only images with either 1 or 3 bands 
can be written out as BMP files.
 at com.sun.media.jai.codecimpl.BMPImageEncoder.encode(BMPImageEncoder.java:123)
 at com.sun.media.jai.opimage.EncodeRIF.create(EncodeRIF.java:79)

Any idea how I could solve this issue?

Jeff
  • 21,744
  • 6
  • 51
  • 55
user224270
  • 557
  • 3
  • 7
  • 19

2 Answers2

25

The easiest way to read in a TIFF and output a BMP would be to use the ImageIO class:

BufferedImage image = ImageIO.read(inputFile);
ImageIO.write(image, "bmp", new File(outputFile));

The only additional thing you would need to do to get this to work is make sure you've added the JAI ImageIO JARs to your classpath, since BMP and TIFF are not handled by the JRE without the plugins from this library.

If you can't use JAI ImageIO for some reason, you can get it to work with your existing code but you'll have to do some additional work. The color model that is being created for the TIFF that you are loading is probably an indexed color model which is not supported by a BMP. You can replace it with the JAI.create("format",...) operation by providing a rendering hint with a key of JAI.KEY_REPLACE_INDEX_COLOR_MODEL.

You may have some luck writing the image read from file into a temporary image and then writing out the temp image:

BufferedImage image = ImageIO.read(inputFile);
BufferedImage convertedImage = new BufferedImage(image.getWidth(), 
    image.getHeight(), BufferedImage.TYPE_INT_RGB);
convertedImage.createGraphics().drawRenderedImage(image, null);
ImageIO.write(convertedImage, "bmp", new File(outputFile));

I'm wondering if you're running into the same index color model issue as with the regular JAI. Ideally you should be using the ImageIO class to get ImageReader and ImageWriter instances for all but the simplest cases so that you can tweak the read and write params accordingly, but the ImageIO.read() and .write() can be finessed to give you what you want.

Jeff
  • 3,669
  • 1
  • 23
  • 33
  • "ImageIO.write(image, "bmp", new File(outputFile))" is stiff not writing able to successfully write the image as a ".bmp" file. when I change the code to ".tiff" instead, then it'll work. – user224270 May 24 '10 at 19:20
  • sorry...there was a small typo. The ImageIO.write should now be writing out the convertedImage, not the original image. – Jeff May 24 '10 at 19:24
  • 3
    The advice "make sure you've added the JAI ImageIO JARs to your classpath" absolutely saved my sanity today! Thank you. – Stewart May 17 '12 at 16:25
  • 1
    An alternative to JAI is TwelveMonkeys ImageIO as suggested in [this question](http://stackoverflow.com/a/16814295/1696114) ([installation guide](https://github.com/haraldk/TwelveMonkeys#installing)). Then you can just use ImageIO.read as normal. No native libs needed like with JAI. – Will Hardwick-Smith Aug 09 '16 at 05:49
  • 2
    ImageIO.read supports TIFFs since Java 9 without additional libraries required. – Hemaolle Apr 14 '18 at 10:25
-2
FileInputStream in = new FileInputStream(imgFullPath);
FileChannel channel = in.getChannel();
ByteBuffer buffer = ByteBuffer.allocate((int)channel.size());
channel.read(buffer);
tiffEncodedImg = Base64.encode(buffer.array()); 

Use this contents(i.e value of "tiffEncodedImg") as src value of img tag in HTML

laalto
  • 150,114
  • 66
  • 286
  • 303