ArrayIndexOutOfBoundsException:4096在读取gif文件时
我能读取png文件。 但是在读取gif文件时获取ArrayIndexOutOfBoundsException:4096。
byte[] fileData = imageFile.getFileData(); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(fileData); RenderedImage image = ImageIO.read(byteArrayInputStream)
抛出的exception看起来像
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)
可能是什么问题,解决方案是什么?
更新3:解决方案
我最终开发了自己的GifDecoder,并在Apache License 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运行时环境(版本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图像。 所以你应该修复这个bug。 以下重现问题的步骤: javac -cp .; PATH_TO_COMMONS_CODEC GIF_OverflowStringList_Test.java java -cp .; PATH_TO_COMMONS_CODEC GIF_OverflowStringList_Test 预期与实际行为: 预期 - 正常完成。 没有输出 实际 - 发生ArrayIndexOutOfBounds。 发生的错误信息/堆栈跟踪: 线程“main”中的exceptionjava.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) 可重复性: 这个bug总是可以复制。
错误报告还提供了重现错误的代码。
更新1
这是一个导致我自己的代码中的错误的图像:
更新2
我尝试使用Apache Commons Imaging读取相同的图像,这导致以下exception:
java.io.IOException:AddStringToTable:codes: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 。
我遇到了你遇到的完全相同的问题,但是我不得不坚持使用ImageIO接口,而其他库都没有。 除了杰克的好答案之外,我只需用几行代码修补现有的GIFImageReader
类,并使其略微有效。
将此链接复制到PatchedGIFImageReader.java
并使用如下:
reader = new PatchedGIFImageReader(null); reader.setInput(ImageIO.createImageInputStream(new FileInputStream(files[i]))); int ub = reader.getNumImages(true); for (int x=0;x
务必将包名更改为您正在使用的任何名称。
不幸的是,结果可能会有所不同,因为补丁是一个1分钟的错误修正,如果超过缓冲区,它基本上只会退出循环。 一些GIF加载很好,其他人有一些视觉文物。
这就是人生。 如果有人知道更好的解决方案而不是我的,请告诉我们。