奇怪的PNG错误:IHDR块的长度不正确 [英] Strange PNG errors: Bad length for IHDR chunk

查看:1437
本文介绍了奇怪的PNG错误:IHDR块的长度不正确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是错误:

 线程main中的异常javax.imageio.IIOException:读取PNG头的I / O错误!在com.sun.imageio.plugins.png.PNGImageReader.readHeader(PNGImageReader.java:307)

在com.sun.imageio.plugins.png.PNGImageReader.readMetadata(PNGImageReader.java:637)在com.sun.imageio.plugins.png.PNGImageReader.readImage(PNGImageReader.java:1212)

在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)在Bundle.dPhIconExists(Bundle.java:158
)中在BundleAnalyzer.supports6(BundleAnalyzer.java:14

。在TheifReader< INIT>(TheifReader.java:14。 )TheifReader.main上的
(TheifReader.java:63)
引起:javax.imageio.IIOException:IHDR块的长度不合适!
at com.sun.imageio.plugins.png.PNGImageReader.readHeader(PNGImageReader.java:239)
... 10更多

并且导致它的代码:

  bimg = ImageIO.read(图标[I]); 

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



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

解决方案

根据< a href =http://www.libpng.org/pub/png/spec/1.2/png-1.2-pdg.html#C.Critical-chunks =nofollow> PNG规范:


4.1.1。 IHDR图像标题



IHDR块必须首先出现。


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



实际上,您的图片似乎是iOS优化的PNG。



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


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


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



您可以通过在其中一个您认为可以正常读取它们的查看器/应用程序中读取图像来修复图像,然后将它们作为普通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 ,获得宽度/高度。


Heres the error:

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

and heres the code causing it:

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

icons is an array of files. The strange thing is that my computer can read the images just fine in any image viewer. Googling the error gave me no results. I have a ton of images I need to read, so is their an alternate way to get the dimensions of an image aside from turning it into a BufferedImage? Will that fix the problem? Is there a way to fix these images? I got them from collecting icons of apps from iOS devices. Tests from my own devices produced no errors, though ones that had previously been sent as part of a zip file, though gathered the same way, produced this error regularly. Everything I know about compression tells me this shouldn't happen. I am not sure where to begin looking, and really need a fix. Here is an example of a failed image.

I should note, for this part of my program, all I need are the image dimensions. I believe this can be obtained through reading metadata, but I also cannot find specifics on this with java.

解决方案

According to the PNG specifiaction:

4.1.1. IHDR Image header

The IHDR chunk must appear FIRST.

Your example image contains a custom critical chunk CgBI as the first chunk, and does not conform to this spec. This is why you get the exception.

Actually, it seems your image is an "iOS optimized PNG".

From http://fileformats.archiveteam.org/wiki/CgBI:

It is not compatible with PNG. Standard PNG decoders that don't support it will fail gracefully, due to an unknown "critical chunk".

Now, what probably should be considered a bug in the com.sun.imageio.plugins.png.PNGImageReader is that it doesn't check that the first chunk is actually a IHDRchunk, before claiming it can read the input.

You can fix the images, by reading them in one of the viewers/apps you say can read them fine, then writing them back as normal PNGs. I tested using Preview on OS X, and it worked fine. Give it a try.

If on OS X (with dev tools), you should also be able to use Apple's modified pngcrush with the following command line:

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


If you just want to get the width/height of the images, you don't need to read full BufferedImages, just get an ImageReader and use its getWidth(0) and getHeight(0) methods (there are plenty examples on SO for this already, no need to repeat).

You could probably also create a quick PNG structure parser, that skips the CgBI chunk, and parses the IHDR directly, to get width/height.

这篇关于奇怪的PNG错误:IHDR块的长度不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆