Java 8中使用Twelve Monkeys库导出TIFF速度慢、文件过大的优化咨询
问题描述
在Java 8中使用TwelveMonkeys库读取.tif/.tiff文件,添加Logo后重新导出为TIFF文件,代码如下:
try { BufferedImage buffLogo = ImageIO.read(fLogo); BufferedImage buffInput = ImageIO.read(fImg); int image_type = buffInput.getType(); //Computing correct position and size of logo here... BufferedImage buffOutput = new BufferedImage(buffInput.getWidth(), buffInput.getHeight(), image_type); File out = new File(outputImg); Graphics2D g = buffOutput.createGraphics(); g.drawImage(buffInput, 0,0,null); g.drawImage(buffLogo, pos_x,pos_y,size_x,size_y,null); g.dispose(); System.out.println("Beginning to write to: '"+out.getAbsolutePath()+"'"); long start = System.currentTimeMillis(); ImageIO.write(buffOutput, "tif", out); long dur = (System.currentTimeMillis() - start) / 1000; System.out.println("Writing finished successfully ("+dur+"s)!"); } catch (IOException e) { System.out.println("Exception:\n"+e.getMessage()); }
测试场景:输入文件约12MB,为TYPE_3BYTE_BGR格式且采用LZW压缩。导出为PNG仅需数秒,文件略小于原文件;导出为JPG速度更快,文件小于1MB。但导出TIFF时,ImageIO.write耗时约5分钟,生成的文件体积达25MB(使用TYPE_INT_ARGB时体积更大,且不需要透明效果)。
疑问:这是TwelveMonkeys库的固有特性,还是需要设置特定参数/使用其他函数,以加快TIFF导出速度并缩小文件体积(接近原文件大小,支持LZW压缩即可)?
解决方案
这不是TwelveMonkeys库的固有特性,问题出在你使用的ImageIO.write简单方法默认未指定压缩参数,导致导出时采用了无压缩或低效压缩方式,进而出现速度慢、文件体积大的问题。通过显式配置TIFF写入参数,指定LZW压缩即可解决。
修改后的核心代码如下,替换原代码中ImageIO.write的部分:
// 替换原有的ImageIO.write代码 try (ImageOutputStream outputStream = ImageIO.createImageOutputStream(out)) { // 获取TwelveMonkeys的TIFF ImageWriter ImageWriter writer = ImageIO.getImageWritersByFormatName("tif").next(); writer.setOutput(outputStream); // 设置写入参数,指定LZW压缩 ImageWriteParam writeParam = writer.getDefaultWriteParam(); writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); writeParam.setCompressionType("LZW"); writeParam.setCompressionQuality(1.0f); // LZW为无损压缩,该参数不影响压缩率 // 写入图像 writer.write(null, new IIOImage(buffOutput, null, null), writeParam); writer.dispose(); }
关键说明:
- 直接使用
ImageWriter而非ImageIO.write,可以更精细地控制输出参数 - 通过
setCompressionType("LZW")指定采用LZW压缩,和原文件的压缩方式一致 - LZW是无损压缩,设置
compressionQuality为1.0即可,该参数对无损压缩无实际影响 - 使用
try-with-resources确保ImageOutputStream自动关闭,避免资源泄漏
这样修改后,导出的TIFF文件体积会接近原文件大小,写入速度也会大幅提升。
内容的提问来源于stack exchange,提问作者Neph
相关产品推荐
相关产品推荐

