Java 奇怪的PNG错误:IHDR区块的长度错误

Java 奇怪的PNG错误:IHDR区块的长度错误,java,png,bufferedimage,javax.imageio,Java,Png,Bufferedimage,Javax.imageio,错误如下: 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(PNGImageRe

错误如下:

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.<init>(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
图标是一组文件。奇怪的是,我的电脑可以在任何图像查看器中很好地读取图像。谷歌搜索错误没有给我任何结果。我需要阅读大量的图像,所以除了将图像转换为BuffereImage之外,它们是否是获取图像尺寸的另一种方法?这能解决问题吗?有没有办法修复这些图像?我是从iOS设备上收集应用图标得到的。来自我自己设备的测试没有产生任何错误,尽管以前作为zip文件的一部分发送的测试以相同的方式收集,但会定期产生此错误。我所知道的关于压缩的一切告诉我这不应该发生。我不知道从哪里开始找,真的需要一个解决办法

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

根据:

4.1.1。IHDR图像头

IHDR区块必须首先出现

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

实际上,您的图像似乎是一个iOS优化的PNG

发件人:

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

现在,在com.sun.imageio.plugins.png.PNGImageReader中可能应该被认为是一个bug的是,它在声明可以读取输入之前没有检查第一个块是否实际上是一个IHDRchunk

你可以通过在一个你认为可以很好地阅读的查看器/应用程序中读取图像,然后将其作为正常PNG写回,来修复这些图像。我在OSX上使用Preview进行了测试,效果很好。试试看

如果在带有开发工具的OS X上,您还应该能够通过以下命令行使用Apple改进的pngcrush:

xcrun -sdk iphoneos pngcrush -revert-iphone-optimizations infile.png outfile.png
如果您只想获得图像的宽度/高度,不需要读取完整的缓冲区图像,只需获取一个ImageReader并使用其getWidth0和getHeight0方法,已经有很多这样的示例,无需重复


您可能还可以创建一个快速的PNG结构解析器,它跳过CgBI块,直接解析IHDR,以获得宽度/高度。

该块及其非法位置表明PNG已被苹果专有的pngcrush版本炒了。试试我自己的。如果包含alpha,则得到预乘;pngdefry也将恢复它。。。解除尝试后,pngcheck投诉非法,除非最近批准了未知的公共区块iDOT。它也被严重压缩:是什么软件创建的?如果您只需要它的大小,请编辑:pngdefry无论如何都会报告这一点,适用于所有类型的png。@Jongware我相信您是对的。这是苹果的专利。这就是问题所在,他们可能会随时改变内部表示。。。根据zlib,页眉/页脚和CRC也被删除。我想CgBI区块应该说明他们应用了哪些违反规范的行为,但它当然没有记录。最尖锐的一点是PNG专家似乎同意苹果的优化——打破了标准,滥用pngcrush的开源/GPL状态——几乎不值得任何计算收益来显示这些图像。。。见f.e.好的,那么这个项目能成功吗?如果不行,我就试试看。
xcrun -sdk iphoneos pngcrush -revert-iphone-optimizations infile.png outfile.png