合并多个 TIF 和 JPEG 文件为单个 TIF 文件会导致文件大小巨大。

huangapple go评论73阅读模式
英文:

Combine multiple tif and Jpeg into single tif file has huge size

问题

以下是您要求的翻译内容:

我正在尝试将多个tif和jpeg文件合并成一个单独的tif文件。

当将多个tif文件合并成一个单独的tif文件时,文件的大小几乎与原始的多个tif文件大小相同(多个tif文件的大小为10MB ----> 单个tif文件的大小为10MB)。这非常理想。

然而,当仅含有许多JPEG文件的tif文件与多个tif文件合并成一个单独的tif文件时,文件大小与原始文件相比要大得多(包含10MB多个tif和JPEG文件的结果是创建了200MB的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();
英文:

I am trying to combine multiple tif and jpeg files into single tif file.

When multiple tif files alone are combined into one single tif file, the file has nearly the same size as of original multiple tif files (10 MB of multiple tif files ----> 10 MB of single tif file). This is perfect.

However, when tif files alone with many number of Jpeg files are combined to single tif file, the file size is huge compared to original (10 MB of multiple tif and Jpeg file resulted in creating 200 MB tif file).

Is there way to prevent the large file size when JPEG file comes?

Code used:

List&lt;BufferedImage&gt; bufferedImageList = new ArrayList&lt;&gt;();
for (String page : pages) {
BufferedImage bufferedImage = ImageIO.read(file);
    bufferedImageList.add(bufferedImage);
}

String filename = &quot;D:\home\example.tif&quot;;
ImageWriter writer = ImageIO.getImageWritersByFormatName(&quot;TIF&quot;).next();

try (ImageOutputStream output = ImageIO.createImageOutputStream(new File(filename))) {
    writer.setOutput(output);

    ImageWriteParam params = writer.getDefaultWriteParam();
    params.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);

    params.setCompressionType(&quot;LZW&quot;);
    params.setCompressionQuality(1.0f);

    writer.prepareWriteSequence(null);

    for (BufferedImage image : bufferedImageList) {
        writer.writeToSequence(new IIOImage(image, null, null), params);
    }
    
    
    writer.endWriteSequence();
	
}

writer.dispose();

答案1

得分: 2

正如@Henry在评论中写道,使用LZW(或任何其他无损)压缩不会像有损JPEG(用于“自然”图像)一样实现相同的压缩效果。在大多数情况下,采用这种方法会导致文件变大,但可以获得最高质量。在许多情况下,这是可以接受的。

另一种选择是在TIFF文件中也使用JPEG压缩,通过指定compressionType"JPEG"。您可能还需要将compressionQuality设置为较低的值(我认为对于ImageIO中的JPEG,默认值为0.7f),以获得更合理的文件大小。

然而,对已经进行过JPEG压缩的图像使用JPEG压缩进行重新压缩,会引入"代际损失",因为JPEG图像通常无法完美重构。从技术上讲,可以通过使用与原始图像相同的表格进行重新压缩,将这种质量损失降到最低,但由于编码器/解码器中的轻微舍入误差(即,最好的方法是使用编写原始图像的相同编码器,并使用完全相同的参数),在实践中难以实现。

第三种选择是使用/创建特定用途的TIFF实用程序,可以将JPEG流原封不动地存储在新的TIFF容器中。这些文件可能不是超级高效的TIFF文件,因为它们不支持条带/块等功能,而且一些非标准输入可能仍然需要重新编写才能生成有效的TIFF文件。这需要一些更多的工作,并需要对TIFF格式有一些深入的了解,但肯定是可行的。

英文:

As @Henry wrote in the comments, using LZW (or any other lossless) compression will not achieve the same compression as lossy JPEG (for "natural" images). Going this route will in most cases result in larger files, but with the highest quality possible. In many cases, this will be acceptable.

An alternative is to use JPEG compression in the TIFF files as well, by specifying compressionType &quot;JPEG&quot;. You probably also need to set the compressionQuality to something lower (I believe 0.7f is the default for JPEG in ImageIO), to get more reasonable file sizes.

However, using JPEG compression to recompress images that was already JPEG compressed, will introduce "generational loss", as JPEGs typically cannot be perfectly reconstructed. It's technically possible to keep this quality loss at a minimum, by recompressing with the same tables as the original, but this is hard to achieve in practice, due to minor rounding errors in encoders/decoders (ie. your best bet is using the same encoder that wrote the original, with the exact same parameters).

A third option is to use/create a special purpose TIFF utility, that can store the JPEG streams as-is inside the new TIFF container. These files may not be super-efficient TIFFs, as they won't support strips/tiles etc, and some non-standard inputs may still require re-writing to produce valid TIFFs. This will be a bit more work and require some in-depth knowledge about the TIFF format, but certainly doable.

huangapple
  • 本文由 发表于 2020年9月13日 23:55:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/63872701.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定