ArrayIndexOutOfBoundsException:读取 gif 文件时出现 4096
Posted
技术标签:
【中文标题】ArrayIndexOutOfBoundsException:读取 gif 文件时出现 4096【英文标题】:ArrayIndexOutOfBoundsException: 4096 while reading gif file 【发布时间】:2014-04-11 04:02:29 【问题描述】:我可以读取 png 文件。但是在读取 gif 文件时得到 ArrayIndexOutOfBoundsException: 4096。
byte[] fileData = imageFile.getFileData();
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(fileData);
RenderedImage image = ImageIO.read(byteArrayInputStream)
抛出的异常看起来像
java.lang.ArrayIndexOutOfBoundsException: 4096
at com.sun.imageio.plugins.gif.GIFImageReader.read(Unknown Source)
at javax.imageio.ImageIO.read(Unknown Source)
at javax.imageio.ImageIO.read(Unknown Source)
可能是什么问题,解决方法是什么?
【问题讨论】:
您尝试阅读的每个 gif 是否都会发生这种情况,还是仅特定的 gif 会发生这种情况 这几乎发生在我所有的 gif 中。 你能提供其中一个 GIF 吗? 您可能有损坏的.gif
文件(例如太短/尚未完全传输左右)或ImageIO
无法理解的 gif 类型。
这显然是内部 GIFImageReader 的错误,从未得到修复。
【参考方案1】:
更新 3:解决方案
我最终开发了自己的 GifDecoder,并在 Apache 许可证 2.0 下将其作为开源发布。你可以从这里得到它:https://github.com/DhyanB/Open-Imaging。它不受ArrayIndexOutOfBoundsException
问题的影响,并提供了不错的性能。
非常感谢任何反馈。特别是,我想知道它是否适用于您的所有图像,以及您是否对它的速度感到满意。
希望对你有帮助(:
初步回答
也许此错误报告与或描述相同的问题:https://bugs.openjdk.java.net/browse/JDK-7132728。
引用:
完整产品版本: java版本“1.7.0_02” Java(TM) SE 运行时环境 (build 1.7.0_02-b13) Java HotSpot(TM) 64 位服务器 VM(内部版本 22.0-b10,混合模式) 其他操作系统版本信息: Microsoft Windows [版本 6.1.7601] 问题描述: 根据规范 http://www.w3.org/Graphics/GIF/spec-gif89a.txt > 字符串表已满时无需发送明码。 但是,GIFImageReader 在字符串表已满时需要清除代码。 GIFImageReader 显然违反了规范。 在现实世界中,有时人们会发现如此高压缩的 gif 图像。 所以你应该修复这个错误。 重现问题的步骤: javac -cp .;PATH_TO_COMMONS_CODEC GIF_OverflowStringList_Test.java java -cp .;PATH_TO_COMMONS_CODEC GIF_OverflowStringList_Test 预期与实际行为: 预期的 - 正常完成。没有输出 实际的 - ArrayIndexOutOfBounds 发生。 发生的错误消息/堆栈跟踪: 线程“主”java.lang.ArrayIndexOutOfBoundsException 中的异常:4096 在 com.sun.imageio.plugins.gif.GIFImageReader.read(GIFImageReader.java:1 075) 在 javax.imageio.ImageIO.read(ImageIO.java:1400) 在 javax.imageio.ImageIO.read(ImageIO.java:1322) 在 GIF_OverflowStringList_Test.main(GIF_OverflowStringList_Test.java:8) 再现性: 这个错误总是可以重现的。
错误报告还提供了重现错误的代码。
更新 1
这是导致我自己代码中的错误的图像:
更新 2
我尝试使用 Apache Commons Imaging 读取相同的图像,导致以下异常:
java.io.IOException: AddStringToTable: 代码: 4096 code_size: 12 在 org.apache.commons.imaging.common.mylzw.MyLzwDecompressor.addStringToTable(MyLzwDecompressor.java:112) 在 org.apache.commons.imaging.common.mylzw.MyLzwDecompressor.decompress(MyLzwDecompressor.java:168) 在 org.apache.commons.imaging.formats.gif.GifImageParser.readImageDescriptor(GifImageParser.java:388) 在 org.apache.commons.imaging.formats.gif.GifImageParser.readBlocks(GifImageParser.java:251) 在 org.apache.commons.imaging.formats.gif.GifImageParser.readFile(GifImageParser.java:455) 在 org.apache.commons.imaging.formats.gif.GifImageParser.readFile(GifImageParser.java:435) 在 org.apache.commons.imaging.formats.gif.GifImageParser.getBufferedImage(GifImageParser.java:646) 在 org.apache.commons.imaging.Imaging.getBufferedImage(Imaging.java:1378) 在 org.apache.commons.imaging.Imaging.getBufferedImage(Imaging.java:1292)
这看起来与我们在 ImageIO 中遇到的问题非常相似,因此我在 Apache Commons JIRA 上报告了该错误:https://issues.apache.org/jira/browse/IMAGING-130。
【讨论】:
哇,这太疯狂了,他们这么久都没有修好。 这里是JDK 1.8.0_45 ... bug 仍然存在:\ 我最近遇到了一个类似的bug。第 11 帧出现越界异常。 很好的解释。感谢您提供测试图像。这个 SO 答案在 IMAGING-130 中链接,另一个贡献者提交了一个已经合并的拉取请求。此修复程序将在 commons-imaging-1.0-alpha2 版本中提供。谢谢!布鲁诺【参考方案2】:我遇到了与您完全相同的问题,但我必须坚持使用 ImageIO 接口,这是其他库所没有的。除了 Jack 的出色回答之外,我只是用几行代码修补了现有的 GIFImageReader
类,并让它勉强工作。
将this link 复制到PatchedGIFImageReader.java
并照此使用:
reader = new PatchedGIFImageReader(null);
reader.setInput(ImageIO.createImageInputStream(new FileInputStream(files[i])));
int ub = reader.getNumImages(true);
for (int x=0;x<ub;x++)
BufferedImage img = reader.read(x);
//Do whatever with the new img bufferedimage
请务必将包名称更改为您正在使用的任何名称。
不幸的是,结果可能会有所不同,因为补丁是一个 1 分钟的错误修复,如果它超过缓冲区,基本上只会退出循环。有些 gif 加载良好,有些则有一些视觉伪影。
这就是生活。如果有人知道比我更好的解决方法,请告诉我。
【讨论】:
以上是关于ArrayIndexOutOfBoundsException:读取 gif 文件时出现 4096的主要内容,如果未能解决你的问题,请参考以下文章