2012-04-25 31 views
4

複数ページのTIFFと圧縮に関するいくつかの質問がありましたが、2つをリンクするものはありませんでした。 This questionは、私が見た限りではありませんし、私を信じられないほど近くに置くので、私は願っています。私はオラクルのフォーラム・スレッドに言及しました(これはTIFFへの複数ページのPDFの圧縮についての話です)、私はこれを行うためにコードを完成させることをやめました。誰も助けることができますか? try/catchを削除して、これを短くしようとします(基本的にはコンソールでメッセージを出力して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; 

} 

それは私がprepareWriteSequenceを呼び出すために必要な言っwriter.writeToSequenceで次のパスに出て失敗しました。私は

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

も以前のwriter.prepareWriteSequence(null)を削除しました。

ファイルを正しくナビゲートしているように見えますが、出力にはレンダリング可能なtifの種類はありません。複数ページまたはそれ以外。

私はJAIをインストールしていますので、圧縮されたイメージを実現するために何らかの方法で使用することができれば素晴らしいと思います。私がTIFFを生成するために使用しているコードはこれを使用していますが、ページに圧縮を追加するまでは何も見ていません。

編集:ios.flush()の束を追加しました。 ios.close();キャッチブロック内で呼び出し、レンダリング不能なTIFFの問題を防止します。しかし、最初のページを超えてページを追加しているわけではありません。

答えて

2

それが助け場合は、これは私が圧縮を設定するTiffImageWriteParamを修正するために使用するコードです:

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は、私自身の列挙型をモデルです:

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は()であります私が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; 
    } 
} 

は、私はあなたのすべてを表示することはできません。私の場合は、よりオープンなアーキテクチャのシーケンスライタを使用するためのエンコーダを設定しました。私はイメージを引っ張り、オプションでデフォルトの圧縮を変更するイベントを発生させ、ライターを作成してparamを作成し、メタデータ/イメージタグを設定し、進行状況を記録してシーケンスを書き込みます。最後に書かれたifdは、tiffエンコーダーが壊れているので、パッチを当てる必要があります。

+0

私は、圧縮アスペクトが動作していると言いたいのですが(50%のファイルサイズが残っているところ)、このように複数ページを試したことはありません(通常JAIを使用します。上記の方法でJAIとの調整を試みると、ファイルサイズの圧縮はなくなります)。それを読んだら、JAIは開発時の特許によってLZWをサポートしていないようだ。 – Robert

関連する問題