2012-04-25 128 views
4

我已經看到關於multipage tiffs和關於壓縮的一些問題的幾個問題,但沒有一個(我見過)連接這兩個問題。 This question就像我見過的一樣近,讓我感覺非常接近,所以我希望。我進入了上面提到的Oracle論壇主題(它正在討論一個多頁PDF到TIFF的壓縮),我想我已經完成了代碼的完成。任何人都可以協助我將刪除try/catches來嘗試縮短這段頭髮(基本上他們所做的只是在控制檯中輸出消息並返回false)。多頁Tiff壓縮

public static boolean CompressedTiff(List<BufferedImage> images, File path) 
{ 
    if (!path.getParentFile().exists()) 
     path.getParentFile().mkdirs(); 
    path.createNewFile(); 
    ImageOutputStream ios; 
     ios = ImageIO.createImageOutputStream(path); 

    Iterator<ImageWriter> imageWriters = ImageIO.getImageWritersByFormatName("TIFF"); 
    ImageWriter writer = (ImageWriter)imageWriters.next(); 
    writer.setOutput(ios); 
    TIFFImageWriteParam writeParam = (TIFFImageWriteParam)writer.getDefaultWriteParam(); 
    writeParam.setCompressionMode(2); 
    writeParam.setCompressionType("LZW"); 
    writer.prepareWriteSequence(null); 

    for(int i = 0; i < images.size(); i++) 
    { 
     ImageTypeSpecifier spec = ImageTypeSpecifier.createFromRenderedImage(images.get(i)); 
     javax.imageio.metadata.IIOMetadata metadata = writer.getDefaultImageMetadata(spec, writeParam); 
     IIOImage iioImage = new IIOImage(images.get(i), null, metadata); 
     writer.writeToSequence(iioImage, writeParam); 
     images.get(i).flush();//modified after release. 

     images.get(i).flush(); 
     writer.endWriteSequence(); 
     ios.flush(); 
     writer.dispose(); 
     ios.close(); 
    } 
    return true; 

} 

它在writer.writeToSequence的下一個傳遞失敗,說我需要調用prepareWriteSequence。我將它改爲

writer.prepareWriteSequence(metadata); 
writer.writeToSequence(iioImage, writeParam); 

也刪除了更早的writer.prepareWriteSequence(null);

它似乎正在導航文件,但是,輸出不是任何類型的可呈現的tif。多頁或其他。

我已經安裝了JAI,所以如果可以用某種方式來實現壓縮的圖像,那太棒了。我使用的代碼生成一個TIFF正在使用這個,但我還沒有看到任何工作,只要將壓縮添加到頁面。

編輯:我添加了一堆ios.flush(); ios.close();調用catch塊,它可以防止不可呈現的TIFF問題。但是,它並沒有在第一頁之外添加任何頁面。

回答

2

如果有幫助,這是我使用的修改TiffImageWriteParam設置壓縮代碼:

try { 
    jWriteParam.setCompressionMode(_compression != TiffCompression.NO_COMPRESSION 
        ? ImageWriteParam.MODE_EXPLICIT : ImageWriteParam.MODE_DISABLED); 

    if (_compression != TiffCompression.NO_COMPRESSION) { 
     // this code corrects the compression if, say, the client code asked for 
     // CCITT but the actual image pixel format was CMYK or some other non-1 bit 
     // image type. 
     TiffCompression mode = recastToValidCompression(_compression, pf); 
     jWriteParam.setCompressionType(getCompressionType(mode)); 
     TIFFCompressor compressor = getTiffCompressor(mode, jWriteParam, shouldUsePredictor(pf)); 
     jWriteParam.setTIFFCompressor(compressor); 
     if (_compression == TiffCompression.JPEG_COMPRESSION) { 
      // Java supports setting to 1.0 (ie 100), but it will not actually do lossless (maybe) 
      if (_jpegQuality == 100 && !jWriteParam.isCompressionLossless()) 
       continue; 
      jWriteParam.setCompressionQuality(toJavaJpegQuality()); 
     } 
    } 
} 
catch (UnsupportedOperationException e) 
{ 
    // this shouldn't get here, but you should consider what to do if it does. 
    // set a default? throw? 
} 

這裏是getTiffCompressor():

private TIFFCompressor getTiffCompressor (TiffCompression compression, TIFFImageWriteParam writeParam, boolean usePredictor) 
{ 
    int predictor = usePredictor 
      ? BaselineTIFFTagSet.PREDICTOR_HORIZONTAL_DIFFERENCING 
      : BaselineTIFFTagSet.PREDICTOR_NONE; 

    switch (compression) 
    { 
    case GROUP_3_FAX_ENCODING: 
     return new TIFFT4Compressor(); 
    case GROUP_4_FAX_ENCODING: 
     return new TIFFT6Compressor(); 
    case JPEG_COMPRESSION: 
     return new TIFFJPEGCompressor(writeParam); 
    case MACINTOSH_PACKBITS: 
     return new TIFFPackBitsCompressor(); 
    case DEFLATE: 
     return new TIFFDeflateCompressor(writeParam, predictor); 
    case LZW: 
     return new TIFFLZWCompressor(predictor); 
    case MODIFIED_HUFFMAN: 
     return new TIFFRLECompressor(); 
    case NO_COMPRESSION: 
    case DEFAULT: 
    default: 
     return null; 
    } 
} 

TiffCompression是我自己的枚舉模型我爲TIFF文件提供的壓縮。最後,這裏是getCompressionType():

private String getCompressionType (TiffCompression compression) 
{ 
    switch (compression) 
    { 
    case GROUP_3_FAX_ENCODING: 
     return "CCITT T.4"; 
    case GROUP_4_FAX_ENCODING: 
     return "CCITT T.6"; 
    case JPEG_COMPRESSION: 
     return "JPEG"; 
    case MACINTOSH_PACKBITS: 
     return "PackBits"; 
    case DEFLATE: 
     return "Deflate"; 
    case LZW: 
     return "LZW"; 
    case MODIFIED_HUFFMAN: 
     return "CCITT RLE"; 
    case NO_COMPRESSION: 
    case DEFAULT: 
    default: 
     return null; 
    } 
} 

現在,我不能告訴你一切,因爲我的代碼是建立在對圖像進行編碼的任意號碼,你是不是,所以我們的代碼結構不同似地。就我而言,我設置了編碼器,以便使用具有更開放架構的序列編寫器。我拉一個圖像,觸發一個事件,可以選擇更改默認壓縮,創建編寫器和寫入參數,設置元數據/圖像標籤,消除進度事件,然後編寫序列。然後,我必須進入並修補最後寫入的ifd,因爲tiff編碼器會將它們寫入中斷狀態,因此需要修補它們。

+0

我想說的是壓縮方面正在工作(在剩餘的50%文件大小附近的某個地方),但我從來沒有試過用這種方法做多頁(我通常使用JAI,但每當我壓縮單個頁面上面提到的方法並試圖使它們與JAI協調一致,文件大小壓縮消失了)。在閱讀之後,由於專利的發展,JAI不支持LZW。 – Robert 2012-04-25 17:04:18