将多个 tif 和 Jpeg 组合成单个 tif 文件具有巨大的大小 [英] Combine multiple tif and Jpeg into single tif file has huge size

查看:71
本文介绍了将多个 tif 和 Jpeg 组合成单个 tif 文件具有巨大的大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将多个 tif 和 jpeg 文件合并为一个 tif 文件.

当多个 tif 文件单独合并为一个 tif 文件时,该文件的大小与原始多个 tif 文件几乎相同(10 MB 的多个 tif 文件----> 10 MB 的单个 tif 文件).这是完美的.

但是,当单独的 tif 文件与许多 Jpeg 文件合并为单个 tif 文件时,文件大小比原始文件大(10 MB 的多个 tif 和 Jpeg 文件导致创建 200 MB 的 tif 文件).

有没有办法防止JPEG文件来的时候文件过大?

使用的代码:

ListbufferedImageList = new ArrayList<>();对于(字符串页面:页面){BufferedImage bufferedImage = ImageIO.read(file);bufferedImageList.add(bufferedImage);}字符串文件名 = "D:\home\example.tif";ImageWriter writer = ImageIO.getImageWritersByFormatName("TIF").next();尝试(ImageOutputStream 输出 = ImageIO.createImageOutputStream(新文件(文件名))){writer.setOutput(输出);ImageWriteParam params = writer.getDefaultWriteParam();params.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);params.setCompressionType(LZW");params.setCompressionQuality(1.0f);writer.prepareWriteSequence(null);对于(缓冲图像图像:缓冲图像列表){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损失",因为 JPEG 通常无法完美重建.通过使用与原始表相同的表重新压缩,在技术上可以将这种质量损失保持在最低限度,但这在实践中很难实现,因为编码器/解码器中的舍入误差很小(即,您最好的选择是使用相同的编写原始代码的编码器,具有完全相同的参数).

第三个选项是使用/创建一个特殊用途的 TIFF 实用程序,它可以在新的 TIFF 容器中按原样存储 JPEG 流.这些文件可能不是超级高效的 TIFF,因为它们不支持条带/图块等,并且一些非标准输入可能仍需要重写以生成有效的 TIFF.这需要做更多的工作,需要对 TIFF 格式有深入的了解,但肯定可行.

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<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();

解决方案

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 "JPEG". 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.

这篇关于将多个 tif 和 Jpeg 组合成单个 tif 文件具有巨大的大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆