问题描述
当单独将多个tif文件组合到一个单个tif文件中时,该文件的大小几乎与原始多个tif文件的大小相同(10 MB的多个tif文件----> 10 MB的单个tif文件)。太完美了。
但是,当将单独的tif文件和许多Jpeg文件组合到一个tif文件中时,文件大小比原始文件大(10 MB的多个tif和Jpeg文件导致创建了200 MB的tif文件)。>
使用的代码:
List<BufferedImage> bufferedImageList = new ArrayList<>();
for (String page : pages) {
BufferedImage bufferedImage = ImageIO.read(file);
bufferedImageList.add(bufferedImage);
}
String filename = "D:\home\example.tif";
ImageWriter writer = ImageIO.getimageWritersByFormatName("TIF").next();
try (ImageOutputStream output = ImageIO.createImageOutputStream(new File(filename))) {
writer.setoutput(output);
ImageWriteParam params = writer.getDefaultWriteparam();
params.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
params.setCompressionType("LZW");
params.setCompressionQuality(1.0f);
writer.prepareWriteSequence(null);
for (BufferedImage image : bufferedImageList) {
writer.writetoSequence(new IIOImage(image,null,null),params);
}
writer.endWriteSequence();
}
writer.dispose();
解决方法
正如@Henry在评论中所写,使用LZW(或任何其他无损)压缩将无法实现与有损JPEG(对于“自然”图像)相同的压缩。在大多数情况下,采用这种方式将产生较大的文件,但可能具有最高的质量。在许多情况下,这是可以接受的。
另一种选择是通过指定compressionType
"JPEG"
在TIFF文件中也使用JPEG压缩。您可能还需要将compressionQuality
设置得较低(我相信0.7f
是ImageIO中JPEG的默认设置),以获取更合理的文件大小。
但是,由于通常无法完美地重建JPEG,因此使用JPEG压缩重新压缩已经进行JPEG压缩的图像会引入"generational loss"。通过使用与原始表相同的表进行重新压缩,在技术上可以将这种质量损失保持在最低水平,但是由于编码器/解码器中的舍入误差较小,因此在实践中很难做到这一点(即,最好的选择是使用相同的表使用原始参数编写的原始编码器。
第三个选择是使用/创建专用的TIFF实用程序,该实用程序可以将JPEG流按原样存储在新的TIFF容器中。这些文件可能不是超级高效的TIFF,因为它们不支持条带/平铺等,并且某些非标准输入可能仍需要重写才能生成有效的TIFF。这将需要更多的工作,并且需要一些有关TIFF格式的深入知识,但肯定是可行的。