我正在使用com.sun.media.imageioimpl.plugins.tiff.TIFFPackBitsCompressor来尝试编码我使用PackBits的tiff字节数组。我对这门课程并不熟悉,也没有找到很多关于如何使用它的例子。但是,当关注javadoc时,我每次尝试编码数据时都会得到一个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文件的更好方法?
如果有什么可以让我的问题更清楚,请告诉我。
谢谢!
答案 0 :(得分:1)
如评论中所述,您不应该直接使用TIFFPackBitsCompressor
,而是在将“PackBits”指定为压缩类型时由JAI ImageIO TIFF插件(TIFFImageWriter
)在内部使用在ImageWriteParam
。如果先将其转换为TIFFImageWriteParam
,也可以在param中传递一个压缩程序实例,但这对于插件不知道的自定义压缩更有用。
另请注意,压缩器只会写入PackBits压缩像素数据,它将不创建完整的TIFF文件。
编写PackBits压缩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:PackBits是一种基于 byte 数据的run-length encoding的非常简单的压缩算法。由于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
这并不奇怪,因为完全随机数据通常不可压缩(没有数据丢失)。对于线性渐变,可能更类似于“摄影”图像数据,我得到了完全不同的结果:
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和Deflate / Zlib算法(带有预测器步骤)执行得更好。对于“真实”数据,可能会有更多噪音,因此您的结果可能介于这两个极端之间。