views:

1928

answers:

5

I have a byte array of several images in the png format. I have to convert this to a tiff file and then into the corresponding byte array. This tiff file will hold multiple images.

I have searced a lot, but I haven't been successful. The catch is. i have to do this in java only!! :) Can anyone provide some insight as regards my issue?

I wont benefit from ImageMagick etc, because i have a server component that handles this conversion, and then saves it in the backend as a tiff. The client gies me a byte array which would translate into a png image.

+2  A: 

Are you trying to do this programatically? You might want to look at ImageMagick (http://www.imagemagick.org/script/index.php)

If you are writing a shell script of some sort (bash, batch) you can invoke the convert command (which is part of that package.) Otherwise, all of the functionality of ImageMagick is available through libraries (C, perl, etc) which you can try linking in with your program.

rascher
I am trying to do this in a java program,I did find one solution, but it converts a single physical file only.I have a byte array in the png foramt. and being a newbie with outrageous deadlines, i have to turn to u guys for help.
Not sure if you still need help with this, but: those libraries might be able to handle byte arrays, I'm not sure. Otherwise, you can write that byte-array to a file, and then use ImageMagick facilities to manipulate that file.
rascher
A: 

I've used ghostscript to create multi-page PDF files, you might be able to do something similar. My particular application had a number of JPG files that I passed to a command line call to ghostscript on windows to create a multi-page PDF.

If I were doing this, I would start by writing the png files to disk. Next use ghostscript to create a multi-page ps file by taking all the PNG files as input, and outputing to a sinlge PostScript document. Finally, use something like ps2tif to do the final conversion. You could either automate the process by programmatically writing out a batch script or just having your app call the command line apps directly.

This is probably easiest to do in a Unix/Linux environment, but it's doable on Win32 with the same tools.

Al Crowley
the problem i have to do this entirely on java
+3  A: 

The JMagick library is a Java interface to ImageMagick, and is likely to be what you want.

bignose
A: 

You should use the JAI (Java Imaging API). It is capable of reading/writing PNG's and at least capable of reading TIFF (writing should be supported too).

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

If writing is not supported use Lizard's Tiff Library for Java (http://www.lizardworks.com/libs.html)

In this thread you can find how to merge multiple files into one TIFF. The poster has Problems changing the TIFF metadata but this should not affect your Problem. http://forums.java.net/jive/thread.jspa?messageID=244190&tstart=0

HaBaLeS
i tried using jai, but could nt really figure out how to write multiple pngs to a tiff file..I am using java 1.5, and the lzard tiff lists downloads compatible with java 1.1.3,
I used the ImageDecoder d=ImageCodec.createImageDecoder("PNG",bytesfromfile,null) to create a png decoder.also, i am trying to decode it as a rendered image,eventually i get an error, png magic number not found....But it is a png on my disk.
HaBaLeS
hiya buddy,Actually while retrieving all png images from a folder, the thumbs.db file which is hidden is also picked up, hence the error. tht took me 3 hrs to find out.. rofl!now, i am able to generate 10 separate tiff files if i have 10 pngs...I tried writing the tiff using the ImageWriter.write(bufferedImage,null,null) if it is the first page and .writeInsert(pageindex,new IIOImage(buferedimage,null,null),null)...Now only the first tiff image is written, and an error saying "Invalid write variant is thrown" while it tries to append.Have any clues!!!!
java.lang.UnsupportedOperationException: Unsupported write variant! at javax.imageio.ImageWriter.unsupported(Unknown Source) at javax.imageio.ImageWriter.writeInsert(Unknown Source) at ads.createTiff(ads.java:104) at ads.readfrompng(ads.java:58) at ads.main(ads.java:188)This is thje error that is thrown...I dunno wer to copy paste ma code, i can do with ur e-mail id :)
hi buddy,just tweeked around with it a bit, and got the output,Though i am able to make a physical file, my solution requires that it be a byte array.i passed a bytearrayoutput stream to the imageoutputstream, and it doesnt wor.If i pass the file boject, it works fine.Can u temme wer r the bytes hiding??
Soory i cant help you in that lvl of detail, maybe you should have a look at how images are stored internal. It allways has a ColorModel (like a Palette) and a Raster (Array) which holds the Per Pixel information.http://www.particle.kth.se/~lindsey/JavaCourse/Book/Part1/Supplements/Chapter11/bufferedImage.html
HaBaLeS
ohk.i tried doin a lotta things,it just writes to a file, but not to the bytearrayoutput stream. and i really dunno y
A: 

Below is the solution.

import javax.imageio.ImageIO; import javax.imageio.ImageWriter; import javax.imageio.IIOImage; import javax.imageio.ImageWriteParam; import javax.imageio.stream.ImageOutputStream; import java.awt.image.BufferedImage; import java.io.*; import java.util.Iterator;

/** * * * This class is used to convert the multiple images in to single multi-pages tiff image file. * */ public class MultiPageTiffGenerator {

private static String compressionType="JPEG";

public static boolean generateMultiPageTiff(String dirName,String outputFileName) throws Exception{ boolean generated=false; ImageOutputStream ios=null; ImageWriter writer=null; try { // verify the directory for the image files File dir = new File(dirName); if(null!=dir && !dir.isDirectory()){ throw new FileNotFoundException("No directory exists with the given name"+dirName); } // verify the images files exist

File[] files = dir.listFiles(); if(null == files || files.length == 0){ throw new FileNotFoundException("No image files to process");

}else{ // Create the output file on the disk File file = new File(dirName+outputFileName+".tif"); ios = ImageIO.createImageOutputStream(file);

// Get the appropriate Tiff Image Writer
Iterator <ImageWriter> writers=ImageIO.getImageWritersByFormatName("tiff");
if(null== writers || ! writers.hasNext()){
 throw new Exception("Appropriate Tiff writer not found");
}

writer = ImageIO.getImageWritersByFormatName("tiff").next();
writer.setOutput(ios);
// Set the compression parameters for Tiff image
ImageWriteParam param = writer.getDefaultWriteParam();
//param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); 
//param.setCompressionType(compressionType); 
//param.setCompressionQuality(0.9F);

// Loop through all image files and write them to output tiff image
for (int i = 0; i < files.length; i++) {
 InputStream fis=null;
 int dotIndex= files[i].getName().lastIndexOf('.');
 dotIndex=dotIndex>0?dotIndex:files[i].getName().length();
 String fileName = files[i].getName().substring(0,dotIndex);
 if(!fileName.equalsIgnoreCase(outputFileName)){
  try{

   fis = new BufferedInputStream(new FileInputStream(files[i]));
   BufferedImage image = ImageIO.read(fis);
   IIOImage img = new IIOImage(image, null, null);
   if (i == 0) {
    writer.write(null, img, param);
   }
   else {
    writer.writeInsert(-1, img, param);
   }
   image.flush();
  }finally{
   if(null!=fis){
    fis.close();
   }
  }
 }

}
ios.flush();
generated=true;

}

}catch(FileNotFoundException ex){ generated=false; }catch(IOException ex){ generated=false; }catch(Exception ex){ generated=false; }finally{ if(null!=ios) ios.close(); if(null!=writer) writer.dispose(); } return generated; }

}

Arvind Jajoo