Java ImageIO IIOException: 不支持的映像类型?

2022-09-01 07:33:22

第一次在Java中使用图像,并且遇到了一些没有很好地记录下来的奇怪异常。下面是失败的代码行:

BufferedImage imgSelected = ImageIO.read(new File("/abs/url/to/file/image.jpg"));

此行将引发具有不受支持的映像类型的 IIOException 作为异常消息。我已经检查并重新检查了实际上是这行抛出异常,File对象是有效的,URL是有效的,并且实际上是一个有效的JPG,在其他图像查看器中加载完全正确。image.jpg

我该怎么做才能获得有关此例外性质的更多信息?这是在Java 7中加载图像的传统方式,还是一种旧的/弃用的方法?关于这些“不支持的图像类型”例外的信息并不多,当然,ImageIO支持JPG!

感谢您的任何帮助!


答案 1

尝试检查 JPEG 的编码。 例如,无法读取 CMYK 编码的 jpeg 图像。AFAIK,ImageIO已经很多年没有更新了,所以你想尝试使用官方的替代方案/扩展:JAI ImageIOImageIO

毫无疑问,JAI ImageIO需要将一些本机库安装到JRE中,这可能是不需要的。我们执行以下操作:

  • 使用Apache Sanselan来检测它是否是JPEG
  • 由于Sanselan无法读取和写入JPEG,因此请使用普通的旧AWT:JPEGCodecJPEGCodec.createJPEGDecoder(...)
  • 将CMYK转换为RGB,然后我们获取读取的光栅并手动转换它(您可以使用ICC配置文件,但手动转换符合我们的需求)BufferedImage

这是我的一个问题,它不支持所有类型的JPEG图像,我在那里陈述了更多关于为什么你得到这个消息的发现:用于检测CMYK图像的JAI ImageIO的纯Java替代品ImageIO


答案 2

不幸的是,我遇到了很多违反标准的JPEG文件。ImageIO特别挑剔,经常拒绝加载图像,这些图像通常由其他软件加载并明显正确显示,对文件格式的检查不那么严格。

它不是很漂亮,但一种解决方法是直接使用Oracle VM内部JPEG解码器(com.sun.image.codec.jpeg.JPEGCodec),因为它似乎可以容忍更多的规格偏差作为ImageIO包装器:

BufferedImage img = 
    JPEGCodec.createJPEGDecoder(inputStream).decodeAsBufferedImage();

这当然不是一个理想的解决方案,因为使用特定于实现的类会将您锁定到特定的VM供应商,并且可能会与较新的VM版本中断,但是如果您只在受控环境中使用该软件,则可能比没有解决方案要好。


推荐