Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java TiffPackBits压缩机-NPE?_Java_Tiff_Javax.imageio_Jai - Fatal编程技术网

Java TiffPackBits压缩机-NPE?

Java TiffPackBits压缩机-NPE?,java,tiff,javax.imageio,jai,Java,Tiff,Javax.imageio,Jai,我正在使用com.sun.media.imageioimpl.plugins.tiff.TIFFPackBitsCompressor对使用PackBits的tiff字节数组进行编码。我不熟悉这门课,也没有找到很多关于如何使用它的例子。但是,在遵循javadoc时,每次尝试对数据进行编码时,我都会得到一个NPE。就我所见,我的值没有一个是空的。我在这一点上用多个值尝试了这些测试,但下面是我最近的一次迭代: TIFFPackBitsCompressor pack =

我正在使用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文件进行编码的更好方法吗

如果有什么可以让我的问题更清楚的话,请告诉我


谢谢大家!

如评论中所述,您不应该直接使用TiffPackBits Compressor,而是在ImageWriteParam中将PackBits指定为压缩类型时,由JAI ImageIO TIFF插件TIFFImageWriter内部使用。如果先将压缩程序实例强制转换为TIFFImageWriteParam,也可以在参数中传递压缩程序实例,但这对于插件未知的自定义压缩程序更有用

还请注意,压缩器将只写入压缩后的像素数据包,而不会创建完整的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:是一种非常简单的基于字节数据的压缩算法。由于16位数据可能在单个样本的高字节和低字节之间变化很大,因此对于此类数据的压缩,打包通常不是一个好的选择

如我在评论中所述,使用完全随机的值,我得到了以下结果:

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算法以及预测器步长的性能要好得多。对于真实数据,可能会有更多的噪声,因此您的结果可能介于这两个极端之间

堆栈跟踪在哪里?无论如何,我不认为你应该自己使用压缩器,相反,当你在ImageWriteParam中将PackBits指定为压缩类型时,它被JAI ImageIO TIFF插件TIFFImageWriter使用。如果先将压缩程序实例转换为TIFFImageWriteParam,也可以在参数中传递压缩程序实例,但这对于插件未知的自定义压缩程序更有用。当文件正在写入且为tiff格式时,它的大小大约是原始文件的两倍。如果有帮助的话,short[]保存16位图像的包装字节。图像为1760x2140像素,原始图像大小为7532800字节没有元数据,只有像素字节。此代码生成的文件为15119390字节,包括tiff元数据。@Sarah您刚刚发现,PackBits是一种非常低效的数据压缩算法,通常16位数据的压缩效率很低。使用上面的代码,我将黑色图像仍然1760x2140 16位/像素压缩为120 KB。用随机噪声填充图像,文件大小变为7.5 MB。将LZW或ZLib与预测器一起使用时,大小大约为10 MB,但由于数据不是随机的,因此它仍可能为您提供更好的结果。