public static void main(String[] args) throws IOException {
        int argIdx = 0;

        // TODO: Proper argument parsing: -t <type> -c <compression>
        int type = args.length > argIdx + 1 ? Integer.parseInt(args[argIdx++]) : -1;
        int compression = args.length > argIdx + 1 ? Integer.parseInt(args[argIdx++]) : 0;

        if (args.length <= argIdx) {
            System.err.println("No file specified");
            System.exit(1);
        }

        File file = new File(args[argIdx++]);

        BufferedImage original;
//        BufferedImage original = ImageIO.read(file);
        ImageInputStream inputStream = ImageIO.createImageInputStream(file);
        try {
            Iterator<ImageReader> readers = ImageIO.getImageReaders(inputStream);

            if (!readers.hasNext()) {
                System.err.println("No reader for: " + file);
                System.exit(1);
            }

            ImageReader reader = readers.next();
            reader.setInput(inputStream);

            ImageReadParam param = reader.getDefaultReadParam();
            param.setDestinationType(reader.getRawImageType(0));

            if (param.getDestinationType() == null) {
                Iterator<ImageTypeSpecifier> types = reader.getImageTypes(0);

                while (types.hasNext()) {
                    ImageTypeSpecifier typeSpecifier = types.next();

                    if (typeSpecifier.getColorModel().getColorSpace().getType() == ColorSpace.TYPE_CMYK) {
                        param.setDestinationType(typeSpecifier);
                    }
                }
            }

            System.err.println("param.getDestinationType(): " + param.getDestinationType());

            original = reader.read(0, param);
        }
        finally {
            inputStream.close();
        }

        System.err.println("original: " + original);

//        BufferedImage image = original;
//        BufferedImage image = new BufferedImage(original.getWidth(), original.getHeight(), BufferedImage.TYPE_INT_ARGB);
//        BufferedImage image = new BufferedImage(original.getWidth(), original.getHeight(), BufferedImage.TYPE_INT_RGB);
//        BufferedImage image = new BufferedImage(original.getWidth(), original.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
//        BufferedImage image = new BufferedImage(original.getWidth(), original.getHeight(), BufferedImage.TYPE_INT_BGR);
//        BufferedImage image = new BufferedImage(original.getWidth(), original.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
        BufferedImage image;
        if (type <= 0 || type == original.getType()) {
            image = original;
        }
        else if (type == BufferedImage.TYPE_BYTE_INDEXED) {
//            image = ImageUtil.createIndexed(original, 256, null, ImageUtil.COLOR_SELECTION_QUALITY | ImageUtil.DITHER_DIFFUSION_ALTSCANS);
            image = ImageUtil.createIndexed(original, 256, null, ImageUtil.COLOR_SELECTION_FAST | ImageUtil.DITHER_DIFFUSION_ALTSCANS);
        }
        else {
            image = new BufferedImage(original.getWidth(), original.getHeight(), type);
            Graphics2D graphics = image.createGraphics();

            try {
                graphics.drawImage(original, 0, 0, null);
            }
            finally {
                graphics.dispose();
            }
        }

        original = null;

        File output = File.createTempFile(file.getName().replace('.', '-'), ".tif");
//        output.deleteOnExit();

        System.err.println("output: " + output);
        TIFFImageWriter writer = new TIFFImageWriter(null);
//        ImageWriter writer = ImageIO.getImageWritersByFormatName("PNG").next();
//        ImageWriter writer = ImageIO.getImageWritersByFormatName("BMP").next();
        ImageOutputStream stream = ImageIO.createImageOutputStream(output);

        try {
            writer.setOutput(stream);

            ImageWriteParam param = writer.getDefaultWriteParam();
            param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
//            param.setCompressionType("None");
//            param.setCompressionType("PackBits");
//            param.setCompressionType("ZLib");
            param.setCompressionType(param.getCompressionTypes()[compression]);
//            if (compression == 2) {
//                param.setCompressionQuality(0);
//            }
            System.err.println("compression: " + param.getLocalizedCompressionTypeName());

            long start = System.currentTimeMillis();
            writer.write(null, new IIOImage(image, null, null), param);
            System.err.println("Write time: " + (System.currentTimeMillis() - start) + " ms");
        }
        finally {
            stream.close();
        }

        System.err.println("output.length: " + output.length());

//        ImageOutputStream stream = ImageIO.createImageOutputStream(output);
//        try {
//            writer.setOutput(stream);
//            writer.prepareWriteSequence(null);
//            for(int i = 0; i < images.size(); i ++){
//                writer.writeToSequence(new IIOImage(images.get(i), null, null), null);
//            }
//            writer.endWriteSequence();
//        }
//        finally {
//            stream.close();
//        }
//        writer.dispose();

        image = null;

        BufferedImage read = ImageIO.read(output);
        System.err.println("read: " + read);

        TIFFImageReader.showIt(read, output.getName());
    }
public static void main ( String [ ] args ) throws IOException { int argIdx = 0 ; int type = args . length > argIdx + 1 ? Integer . parseInt ( args [ argIdx ++ ] ) : - 1 ; int compression = args . length > argIdx + 1 ? Integer . parseInt ( args [ argIdx ++ ] ) : 0 ; if ( args . length <= argIdx ) { System . err . println ( "No file specified" ) ; System . exit ( 1 ) ; } File file = new File ( args [ argIdx ++ ] ) ; BufferedImage original ; ImageInputStream inputStream = ImageIO . createImageInputStream ( file ) ; try { Iterator < ImageReader > readers = ImageIO . getImageReaders ( inputStream ) ; if ( ! readers . hasNext ( ) ) { System . err . println ( "No reader for: " + file ) ; System . exit ( 1 ) ; } ImageReader reader = readers . next ( ) ; reader . setInput ( inputStream ) ; ImageReadParam param = reader . getDefaultReadParam ( ) ; param . setDestinationType ( reader . getRawImageType ( 0 ) ) ; if ( param . getDestinationType ( ) == null ) { Iterator < ImageTypeSpecifier > types = reader . getImageTypes ( 0 ) ; while ( types . hasNext ( ) ) { ImageTypeSpecifier typeSpecifier = types . next ( ) ; if ( typeSpecifier . getColorModel ( ) . getColorSpace ( ) . getType ( ) == ColorSpace . TYPE_CMYK ) { param . setDestinationType ( typeSpecifier ) ; } } } System . err . println ( "param.getDestinationType(): " + param . getDestinationType ( ) ) ; original = reader . read ( 0 , param ) ; } finally { inputStream . close ( ) ; } System . err . println ( "original: " + original ) ; BufferedImage image ; if ( type <= 0 || type == original . getType ( ) ) { image = original ; } else if ( type == BufferedImage . TYPE_BYTE_INDEXED ) { image = ImageUtil . createIndexed ( original , 256 , null , ImageUtil . COLOR_SELECTION_FAST | ImageUtil . DITHER_DIFFUSION_ALTSCANS ) ; } else { image = new BufferedImage ( original . getWidth ( ) , original . getHeight ( ) , type ) ; Graphics2D graphics = image . createGraphics ( ) ; try { graphics . drawImage ( original , 0 , 0 , null ) ; } finally { graphics . dispose ( ) ; } } original = null ; File output = File . createTempFile ( file . getName ( ) . replace ( '.' , '-' ) , ".tif" ) ; System . err . println ( "output: " + output ) ; TIFFImageWriter writer = new TIFFImageWriter ( null ) ; ImageOutputStream stream = ImageIO . createImageOutputStream ( output ) ; try { writer . setOutput ( stream ) ; ImageWriteParam param = writer . getDefaultWriteParam ( ) ; param . setCompressionMode ( ImageWriteParam . MODE_EXPLICIT ) ; param . setCompressionType ( param . getCompressionTypes ( ) [ compression ] ) ; System . err . println ( "compression: " + param . getLocalizedCompressionTypeName ( ) ) ; long start = System . currentTimeMillis ( ) ; writer . write ( null , new IIOImage ( image , null , null ) , param ) ; System . err . println ( "Write time: " + ( System . currentTimeMillis ( ) - start ) + " ms" ) ; } finally { stream . close ( ) ; } System . err . println ( "output.length: " + output . length ( ) ) ; image = null ; BufferedImage read = ImageIO . read ( output ) ; System . err . println ( "read: " + read ) ; TIFFImageReader . showIt ( read , output . getName ( ) ) ; }
Test