将多个 tif 和 Jpeg 组合成一个巨大的 tif 文件
Combine multiple tif and Jpeg into single tif file has huge size
我正在尝试将多个 tif 和 jpeg 文件合并为一个 tif 文件。
当单独的多个tif文件组合成一个单独的tif文件时,该文件的大小与原始多个tif文件的大小几乎相同(10 MB多个tif文件----> 10 MB单个tif文件) .这太完美了。
但是,当单独的 tif 文件与许多 Jpeg 文件组合成单个 tif 文件时,文件大小比原始文件大(10 MB 的多个 tif 和 Jpeg 文件导致创建 200 MB 的 tif 文件)。
有没有办法防止JPEG文件来的时候文件太大?
使用的代码:
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(对于“自然”图像)相同的压缩。在大多数情况下,走这条路会产生更大的文件,但质量可能是最高的。在许多情况下,这是可以接受的。
另一种方法是在 TIFF 文件中也使用 JPEG 压缩,方法是指定 compressionType
"JPEG"
。您可能还需要将 compressionQuality
设置为较低的值(我相信 0.7f
是 ImageIO 中 JPEG 的默认值),以获得更合理的文件大小。
但是,使用 JPEG 压缩来重新压缩已经进行 JPEG 压缩的图像会引入 "generational loss",因为 JPEG 通常无法完美重建。通过使用与原始表格相同的表格重新压缩,在技术上可以将这种质量损失保持在最低限度,但由于 encoders/decoders 中的小舍入误差(即你最好的选择是使用使用与原始编码器相同的编码器,具有完全相同的参数)。
第三个选项是 use/create 一个特殊用途的 TIFF 实用程序,它可以将 JPEG 流 as-is 存储在新的 TIFF 容器中。这些文件可能不是 super-efficient TIFF,因为它们不支持 strips/tiles 等,并且某些 non-standard 输入可能仍需要 re-writing 才能生成有效的 TIFF。这将需要更多的工作,并且需要一些 in-depth 有关 TIFF 格式的知识,但肯定可行。
我正在尝试将多个 tif 和 jpeg 文件合并为一个 tif 文件。
当单独的多个tif文件组合成一个单独的tif文件时,该文件的大小与原始多个tif文件的大小几乎相同(10 MB多个tif文件----> 10 MB单个tif文件) .这太完美了。
但是,当单独的 tif 文件与许多 Jpeg 文件组合成单个 tif 文件时,文件大小比原始文件大(10 MB 的多个 tif 和 Jpeg 文件导致创建 200 MB 的 tif 文件)。
有没有办法防止JPEG文件来的时候文件太大?
使用的代码:
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(对于“自然”图像)相同的压缩。在大多数情况下,走这条路会产生更大的文件,但质量可能是最高的。在许多情况下,这是可以接受的。
另一种方法是在 TIFF 文件中也使用 JPEG 压缩,方法是指定 compressionType
"JPEG"
。您可能还需要将 compressionQuality
设置为较低的值(我相信 0.7f
是 ImageIO 中 JPEG 的默认值),以获得更合理的文件大小。
但是,使用 JPEG 压缩来重新压缩已经进行 JPEG 压缩的图像会引入 "generational loss",因为 JPEG 通常无法完美重建。通过使用与原始表格相同的表格重新压缩,在技术上可以将这种质量损失保持在最低限度,但由于 encoders/decoders 中的小舍入误差(即你最好的选择是使用使用与原始编码器相同的编码器,具有完全相同的参数)。
第三个选项是 use/create 一个特殊用途的 TIFF 实用程序,它可以将 JPEG 流 as-is 存储在新的 TIFF 容器中。这些文件可能不是 super-efficient TIFF,因为它们不支持 strips/tiles 等,并且某些 non-standard 输入可能仍需要 re-writing 才能生成有效的 TIFF。这将需要更多的工作,并且需要一些 in-depth 有关 TIFF 格式的知识,但肯定可行。