使用 IOUtils 和 ImageIO 写入图像文件有啥区别

Posted

技术标签:

【中文标题】使用 IOUtils 和 ImageIO 写入图像文件有啥区别【英文标题】:What is the difference between using IOUtils and ImageIO for writing an image file使用 IOUtils 和 ImageIO 写入图像文件有什么区别 【发布时间】:2013-06-10 08:24:37 【问题描述】:

我有一个 tiff 图像作为 Base64 编码字符串存储在一个文件中。我的目标是从中创建一个 tiff 文件。这就是我正在做的事情:

String base64encodedTiff = IOUtils.toString(new FileInputStream("C:/tiff-attachment.txt"));    
byte[] imgBytes = DatatypeConverter.parseBase64Binary(base64encodedTiff);
BufferedImage bufImg = ImageIO.read(new ByteArrayInputStream(imgBytes));   
ImageIO.write(bufImg, "tiff", new File("c:/new-darksouls-imageIO-tiff.tiff")); 

ImageIO.write() 正在抛出 IllegalArgumentException,因为 bufImg 为空。我不明白我在这里做错了什么。

相反如果我用IOUtils来写,效果很好:

IOUtils.write(imgBytes, new FileOutputStream("c:/new-darksouls-io-tiff.tiff"));

请帮我理解

    为什么 ImageIO 会抛出异常 什么是我想要实现的正确 API 和方法。

【问题讨论】:

【参考方案1】:

ImageIO 会很有用,例如,如果您想将 PNG 转换为 JPEG。由于您不需要操作图像或转换为另一种格式,因此不必为 ImageIO 烦恼。只需使用IOUtils.write() 逐字保存 TIFF 数据。

ImageIO.read() 正在返回一个空图像,因为它无法读取 TIFF 文件,可能是因为 TIFF 不是标准 ImageIO 插件格式之一。此处列出了支持的标准图像格式:

http://docs.oracle.com/javase/6/docs/api/javax/imageio/package-summary.html

附加说明——您发布的代码将整个图像缓冲在内存中。如果您担心有效地使用内存,请考虑使用某种 Base64 解码输入流来即时执行解码。可能看起来像这样:

try (FileOutputStream out = new FileOutputStream("c:/new-darksouls-io-tiff.tiff");
     FileInputStream in = new FileInputStream("C:/tiff-attachment.txt");
     Base64InputStream decodedIn = new Base64InputStream(in)) 

    IOUtils.copy(decodedIn, out);

【讨论】:

将 ImageIO 代码更改为使用 png 而不是 tiff 格式仍然会引发相同的错误。在 bufImg 为空的 ImageIO.write() 的第一行中直接抛出错误 问题是 ImageIO.read() 返回 null (因为它无法读取 TIFF)。更改 ImageIO.write() 中的输出格式不会产生任何影响,因为您没有要写入的图像! 明白你的意思,我应该尝试其他支持的文件格式的示例 呃,如果你使用 Java 7 的 try-with-resources,为什么在有 Files 的情况下使用 IOUtils

以上是关于使用 IOUtils 和 ImageIO 写入图像文件有啥区别的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 Java ImageIO 标准库读写 TIFF 图像文件

IOUtils.copy 是不是会阻塞直到写入完成?

如何更改 ImageIO 写入字节序

python图像数据读取利器-imageio库的使用

如何使用 imageio 调整图像大小以获得正确的 ICO 文件?

无法使用 ImageIO.read(文件文件)读取 JPEG 图像