views:

1096

answers:

2

-Edit- FYI.. I am converting b&w documents scanned in as greyscale or color.

1)The first solution worked, it just reversed black & white (black background, white text). It also took nearly 10 minutes.
2)The JAI solution in the 2nd answer didn't work for me. I tried it before posting here.

Has anyone worked with other libraries free or pay that handle image manipulation well?

-Original- I am trying to convert an PNG to a bitonal TIFF using Java ImageIO. Has anyone had any luck doing this? I have got it to convert from PNG to TIFF. I am not sure if I need to convert the BufferedImage (PNG) that I read in or convert on the TIFF as I write it. I have searched and searched but nothing seems to work? Does anyone have an suggestions where to look?

Here is the code that converts...

public static void test() throws IOException {

 String fileName = "4848970_1";
 // String fileName = "color";
 String inFileType = ".PNG";
 String outFileType = ".TIFF";

 File fInputFile = new File("I:/HPF/UU/" + fileName + inFileType);
 InputStream fis = new BufferedInputStream(new FileInputStream(fInputFile));
 ImageReaderSpi spi = new PNGImageReaderSpi();
 ImageReader reader = spi.createReaderInstance();
 ImageInputStream iis = ImageIO.createImageInputStream(fis);
 reader.setInput(iis, true);
 BufferedImage bi = reader.read(0);

 int[] xi = bi.getSampleModel().getSampleSize();

 for (int i : xi) {
  System.out.println("bitsize " + i);
 }

 ImageWriterSpi tiffspi = new TIFFImageWriterSpi();
 TIFFImageWriter writer = (TIFFImageWriter) tiffspi.createWriterInstance();

 // TIFFImageWriteParam param = (TIFFImageWriteParam) writer.getDefaultWriteParam();
 TIFFImageWriteParam param = new TIFFImageWriteParam(Locale.US);
 String[] strings = param.getCompressionTypes();
 for (String string : strings) {
  System.out.println(string);
 }

 param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
 param.setCompressionType("LZW");

 File fOutputFile = new File("I:\\HPF\\UU\\" + fileName + outFileType);
 OutputStream fos = new BufferedOutputStream(new FileOutputStream(fOutputFile));
 ImageOutputStream ios = ImageIO.createImageOutputStream(fos);

 writer.setOutput(ios);
 writer.write(null, new IIOImage(bi, null, null), param);

 ios.flush();
 writer.dispose();
 ios.close();

}

I have tried changing the compression to type "CCITT T.6" as that appears to be what I want, but I get an error " Bits per sample must be 1 for T6 compression! " Any suggestion would be appreciated.

+2  A: 

Most likely, you want something like this to convert to 1 bit before you save to TIFF with CCITT compression.

To expound a little bit - be aware that converting from other bit depths to 1 bit is non-trivial. You are doing a data reduction operation and there are dozens of domain specific solutions which vary greatly in output quality (blind threshold, adaptive threshold, dithering, local threshold, global threshold and so on). None of them are particularly good at all image types (adaptive threshold is pretty good for documents, but lousy for photographs, for example).

plinth
All of these are scanned documents.
CFreiner
A: 

As plinth said, you have to do the conversion, Java won't do it magically for you... If the PNG image is already black & white (as it seems, looking at your comment), using a threshold is probably the best solution.

Somebody seems to have the same problem: HELP: how to compress the tiff. A solution is given on the thread (untested!).

PhiLho