2011年11月9日 星期三

JAI TIFF Split 很慢的解決方式

這個是協助外包廠商解決 Java 使用 JAI 去切割 TIFF 檔的分頁很慢的問題

TIFF 檔基本上可以分為 單檔單頁 , 或是 單檔多頁
因為廠商寫出來的切檔程式速度很慢 , 因此本於能夠盡快導入系統的責任感 , 進行了協助測試



TIFFSeparater Ver 3.0

這個也有變快 , 沒有使用到 NIO , FileChannel ; 取消 FineInputStream ;
因為再次測試的結果 , 發現跟 NIO 也沒有太大的影響 , 所以應該是  Stream 的問題


//ImageDecoder decoder = ImageCodec.createImageDecoder("tiff", fis, null);  //java.io.FileInputStream  這個版本很慢

ImageDecoder decoder = ImageCodec.createImageDecoder("tiff" , stream , null);//com.sun.media.jai.codec.SeekableStream

                                                                                                      //com.sun.media.jai.codec.FileSeekableStream         (A)都在可以接受的速度

                                                                                                      //com.sun.media.jai.codec.ByteArraySeekableStream   (B) 都在可以接受的速度

--------------------------------
TIFFSeparater.java


import java.awt.image.RenderedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Collection;
import java.util.UUID;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.time.StopWatch;

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.ImageEncoder;
import com.sun.media.jai.codec.SeekableStream;
import com.sun.media.jai.codec.TIFFDirectory;
import com.sun.media.jai.codec.TIFFEncodeParam;

public class TIFFSeparater {
        public static void splitImage(Collection imgFiles, String forms, File destPath) throws IOException {

        System.out.println("Enter split methd ");
        StopWatch stopWatch = new StopWatch();

        stopWatch.start();
        FileUtils.cleanDirectory(destPath);
        stopWatch.stop();
        System.out.println("FileUtils.cleanDirectory Spend time: " + stopWatch.getTime()/1000f);
        stopWatch.reset();


        String[] form_id = forms.split(";");
        ArrayList file_list = new ArrayList();
        for (File imgFile : imgFiles) {  //for1
           stopWatch.start();
        //FileInputStream fis = new FileInputStream(imgFile);         
        //FileChannel fisChannel = fis.getChannel();
        //ByteBuffer buffer = ByteBuffer.allocate((int)fisChannel.size());
            //fisChannel.read(buffer);
            //fisChannel.close();
            //SeekableStream stream = new ByteArraySeekableStream(buffer.array());
       
        SeekableStream stream = new FileSeekableStream(imgFile);
       
            //ImageDecoder decoder = ImageCodec.createImageDecoder("tiff", fis, null);
        ImageDecoder decoder = ImageCodec.createImageDecoder("tiff" , stream , null);
        stopWatch.stop();
             System.out.println("ImageCodec.createImageDecoder(" + imgFile + ") Spend time: " + stopWatch.getTime()/1000f);
            stopWatch.reset();
       
       
                int page_count = decoder.getNumPages();
                for(int i = 0; i < page_count; i++) {   //for2
               
                       
                    File dest = new File(destPath, UUID.randomUUID().toString() + ".tif");
                   stopWatch.start();
                    RenderedImage ri = decoder.decodeAsRenderedImage(i);
                   stopWatch.stop();
                    System.out.println("decoder.decodeAsRenderedImage( " + i + " ) Spend time: " + stopWatch.getTime()/1000f);
                   stopWatch.reset();

                   stopWatch.start();
                    TIFFDirectory td = (TIFFDirectory)ri.getProperty("tiff_directory");
                   stopWatch.stop();
                    System.out.println("ri.getProperty(tiff_directory) Spend time: " + stopWatch.getTime()/1000f);
                   stopWatch.reset();

                   stopWatch.start();
                    TIFFEncodeParam tep = new TIFFEncodeParam();
                     stopWatch.stop();
                  System.out.println("new TIFFEncodeParam() Spend time: " + stopWatch.getTime()/1000f);
                   stopWatch.reset();

                   stopWatch.start();
                    tep.setExtraFields(td.getFields());
                     stopWatch.stop();
                  System.out.println("td.getFields() Spend time: " + stopWatch.getTime()/1000f);
                   stopWatch.reset();

                   stopWatch.start();
                    tep.setCompression(TIFFEncodeParam.COMPRESSION_GROUP4);
                     stopWatch.stop();
                  System.out.println("ep.setCompression Spend time: " + stopWatch.getTime()/1000f);
                   stopWatch.reset();


                   stopWatch.start();
                    FileOutputStream fos = new FileOutputStream(dest);
                    FileChannel fosChannel = fos.getChannel();
                   
                     stopWatch.stop();
                  System.out.println("new FileOutputStream(" + dest +") Spend time: " + stopWatch.getTime()/1000f);
                   stopWatch.reset();




                   stopWatch.start();                 
                   ImageEncoder encoder = ImageCodec.createImageEncoder("tiff", fos, tep);
                 
                        encoder.encode(ri);
                    fos.flush();
                    fos.close();
                        IOUtils.closeQuietly(fos);               
             
                     stopWatch.stop();
                  System.out.println("new FileOutputStream(" + dest +") Spend time: " + stopWatch.getTime()/1000f);

                   stopWatch.reset();


                    file_list.add(dest.getName());
                }  //for2
                //IOUtils.closeQuietly(fis);
}        //for1
       
        FileUtils.writeLines(new File(destPath, "Context.dat"), file_list, "\r\n");
        System.out.println("Exit split method");
    }

public final static void main(String args[]) throws Exception {

if (args == null || args.length < 2)
{
System.err.println("Check your agrument is correct!!");
System.exit(-1);
}
Collection tifs = new ArrayList();
StringBuilder formsBuilder = new StringBuilder();
String filesString [] = args [0].split(";");
for (String string : filesString) {
tifs.add(new File(string));
formsBuilder.append( string + ";");
}

// tifs.add(new File("D:/111252f58002242b.tif"));
// tifs.add(new File("D:/111252f58002242d.tif"));
// tifs.add(new File("D:/111252f58002242c.tif"));

System.out.println(formsBuilder.toString());
System.out.println(args[1]);
splitImage(tifs,formsBuilder.toString(),new File(args[1]));

}

}