奇怪的PNG错误:IHDR块的长度不正确

inheritance人错误:

Exception in thread "main" javax.imageio.IIOException: I/O error reading PNG header! at com.sun.imageio.plugins.png.PNGImageReader.readHeader(PNGImageReader.java:307) at com.sun.imageio.plugins.png.PNGImageReader.readMetadata(PNGImageReader.java:637) at com.sun.imageio.plugins.png.PNGImageReader.readImage(PNGImageReader.java:1212) at com.sun.imageio.plugins.png.PNGImageReader.read(PNGImageReader.java:1560) at javax.imageio.ImageIO.read(ImageIO.java:1422) at javax.imageio.ImageIO.read(ImageIO.java:1282) at Bundle.iconExists(Bundle.java:139) at Bundle.dPhIconExists(Bundle.java:158) at BundleAnalyzer.supports6(BundleAnalyzer.java:14) at TheifReader.(TheifReader.java:14) at TheifReader.main(TheifReader.java:63) Caused by: javax.imageio.IIOException: Bad length for IHDR chunk! at com.sun.imageio.plugins.png.PNGImageReader.readHeader(PNGImageReader.java:239) ... 10 more 

以及导致它的代码:

  bimg = ImageIO.read(icons[i]); 

icons是一个文件数组。 奇怪的是,我的电脑可以在任何图像浏览器中读取图像。 谷歌搜索错误没有给我带来任何结果。 我需要阅读大量图像,除了将图像转换为BufferedImage之外,还有另一种获取图像尺寸的方法吗? 这会解决问题吗? 有没有办法修复这些图像? 我通过从iOS设备收集应用程序图标来获取它们。 来自我自己的设备的测试没有产生任何错误,尽管之前作为zip文件的一部分发送的测试虽然以相同的方式收集,但是会定期产生此错误。 我所知道的关于压缩的一切都告诉我这不应该发生。 我不知道从哪里开始寻找,真的需要修复。 以下是失败图像的示例 。

我应该注意,对于我的程序的这一部分,我需要的只是图像尺寸。 我相信这可以通过阅读元数据来获得,但我也找不到与java相关的细节。

根据PNG的规定 :

4.1.1。 IHDR图像标题

IHDR块必须首先出现。

您的示例图像包含自定义关键块CgBI作为第一个块,并且不符合此规范。 这就是你得到例外的原因。

实际上,您的图像似乎是“iOS优化的PNG”。

来自http://fileformats.archiveteam.org/wiki/CgBI :

它与PNG不兼容。 由于未知的“关键块”,不支持它的标准PNG解码器将会正常失败。

现在, com.sun.imageio.plugins.png.PNGImageReader可能应该被视为错误的是,在声明它可以读取输入之前,它不检查第一个块实际上是IHDR块。

您可以通过在其中一个您认为可以正常读取它们的查看器/应用程序中读取图像来修复图像,然后将它们作为普通PNG写回。 我在OS X上使用Preview进行了测试,它运行良好。 试一试。

如果在OS X上(使用开发工具),您还应该能够使用Apple的修改后的pngcrush和以下命令行:

 xcrun -sdk iphoneos pngcrush -revert-iphone-optimizations infile.png outfile.png 

如果你只想获得图像的宽度/高度,你不需要读取完整的BufferedImages ,只需要获得一个ImageReader并使用它的getWidth(0)getHeight(0)方法(这里有很多关于SO的例子)已经,无需重复)。

你也可以创建一个快速的PNG结构解析器,跳过CgBI块,直接解析IHDR ,得到宽度/高度。