2017-03-24 9 views
0

私はcombit.imageioimpl.plugins.tiff.TIFFPackBitsCompressorを使用して、PackBitsを使用しているtiffバイトの配列をエンコードしようとしています。私はこのクラスに慣れておらず、使用方法に関する多くの例を見つけていません。しかし、javadocに従うと、データをエンコードしようとするたびにNPEを取得しています。私が見る限りでは、私の価値のどれもがヌルです。私は、この時点で複数の値を持つこれらのテストを試してみましたが、以下の私の最も最近の反復できました:TIFFPackBitsCompressor - NPE?

   TIFFPackBitsCompressor pack = new TIFFPackBitsCompressor(); 
       //bImageFromConvert is a 16-bit BufferedImage with all desired data. 
       short[] bufferHolder = ((DataBufferUShort) bImageFromConvert.getRaster().getDataBuffer()).getData(); 
       //Since bImageFromConvert is 16-bits, the short array isn't the right length. 
       //The below conversion handles tihs issue 
       byte[] byteBuffer = convertShortToByte(bufferHolder); 
       //I'm not entirely sure what this int[] in the parameters should be. 
       //For now, it is a test int[] array containing all 1s 
       int[] testint = new int[byteBuffer.length]; 
       Arrays.fill(testint, 1); 
       //0 offset. dimWidth = 1760, dimHeight = 2140. Not sure what that last param is supposed to be in layman's terms. 
       //npe thrown at this line. 
       int testOut = pack.encode(byteBuffer, 0, dimWidth, dimHeight, testint, 1); 

誰もが何が起こっているかのように任意の洞察力を持っていますか?また、利用可能であれば、JavaプログラムでPackBitsを使用してTIFFファイルをエンコードする方がいいですか?

私の質問をもっと明確にすることがあれば教えてください。

ありがとうございました!

+2

スタックトレースはどこですか?とにかく、私はあなたが圧縮機を自分で使うはずではないと思っています。代わりに、 'ImageWriteParam'の圧縮タイプとして" PackBits "を指定すると、JAI ImageIO TIFFプラグイン(' TIFFImageWriter')で使用されます。最初に 'TIFFImageWriteParam'にキャストすると、コンプレッサーのインスタンスをparamに渡すこともできますが、これはプラグインが知らないカスタム圧縮にはもっと便利です。 – haraldK

答えて

1

としてはコメントで、あなたはあなたがImageWriteParamの圧縮タイプとして「パックビッツ」を指定する場合、直接、代わりにそれはJAI ImageIOでのTIFFプラグイン(TIFFImageWriter)によって内部的に使用されますTIFFPackBitsCompressor使用することになっていないと述べました。最初にTIFFImageWriteParamにキャストすると、コンプレッサーのインスタンスをパラメーターに渡すこともできますが、これはプラグインが認識できないカスタム圧縮にはより便利です。

また、コンプレッサーはPackBits圧縮されたピクセルデータのみを書き込むので、ではなく、フルTIFFファイルを作成します。

パックビッツ圧縮TIFFファイルを書くの通常の方法は次のとおりです。

BufferedImage image = ...; // Your input image 

ImageWriter writer = ImageIO.getImageWritersByFormatName("TIFF").next(); // Assuming a TIFF plugin is installed 

try (ImageOutputStream out = ImageIO.createImageOutputStream(...)) { // Your output file or stream 
    writer.setOutput(out); 

    ImageWriteParam param = writer.getDefaultWriteParam(); 
    param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); 
    param.setCompressionType("PackBits"); 

    writer.write(null, new IIOImage(image, null, null), param); 
} 

writer.dispose(); 

上記のコードは、JAIのImageIOとTwelveMonkeys ImageIOでのTIFFのプラグインの両方を使用して正常に動作する必要があります。


PS:PackBitsrun-length encodingバイトのデータをもとに、非常に単純な圧縮アルゴリズムです。 1つのサンプルの上位バイトと下位バイトの間では16ビットのデータが大きく変動する可能性があるため、PackBitsは一般にそのようなデータの圧縮には適していません。私は以下の結果を得た完全にランダムな値を使用して、私のコメントで述べたように

は:完全にランダムなデータ(データ損失なし)、一般的に圧縮できないよう

Compression  | File size 
-----------------|----------------- 
None    | 7 533 680 bytes 
PackBits   | 7 593 551 bytes 
LZW w/predictor | 10 318 091 bytes 
ZLib w/predictor | 10 318 444 bytes 

これは、非常に驚​​くべきことではありません。 「写真」画像データIが完全に異なる結果を得た、より類似していてもよい直線勾配、について:ご覧のとおり

Compression  | File size 
-----------------|----------------- 
None    | 7 533 680 bytes 
PackBits   | 7 588 779 bytes 
LZW w/predictor | 200 716 bytes 
ZLib w/predictor | 144 136 bytes 

は、ここにLZWと(予測ステップで)デフレート/ Zlibのアルゴリズムは、より良い実行されます。 「実際の」データの場合、ノイズが多い可能性があります。その結果は、これらの極端な状況の間にある可能性があります。

+0

ファイルは書き込み中で、TIFF形式ですが、元のファイルの約2倍のサイズです。役立つならば、short []は16ビットイメージのラップされたバイトを保持します。イメージは1760x2140ピクセルで、元のイメージサイズは7,532,800バイトです(メタデータなし、ピクセルバイトのみ)。このコードの結果のファイルは、15,119,390バイト(tiffメタデータを含む)です。 – Sarah

+0

@Sarahあなたは、PackBitsがあなたのデータにとって非常に非効率な圧縮アルゴリズムであることを発見しました(これは一般的に16ビットデータでは非効率的です)。上記のコードを使用して、黒い画像(まだ1760x2140 16ビット/ピクセル)を120Kバイトに圧縮しました。ランダムノイズで画像を埋め込むと、ファイルサイズは7,5 Mバイトになりました。 LZWまたはZLibをプレディクタとともに使用すると、約10Mバイトのサイズが得られますが、データがランダムではないため、より良い結果が得られる場合があります。 – haraldK