DK8-ImageIO读取gif历史遗留问题:ArrayIndexOutOfBoundsException: 4096

简介: 尊敬的家人朋友们,大家好!今天我们将探讨一些Java JDK 6~8版本中的gif读取的历史遗留问题,特别是那令人头疼的ArrayIndexOutOfBoundsException: 4096异常。在过去的几年里,许多Java开发者在处理GIF图像时可能遇到过这个问题,现在让我们一起来了解其中的原因和解决方案。

imageio.jpg

尊敬的家人朋友们,大家好!今天我们将探讨一些Java JDK 6~8版本中的gif读取的历史遗留问题,特别是那令人头疼的ArrayIndexOutOfBoundsException: 4096异常。在过去的几年里,许多Java开发者在处理GIF图像时可能遇到过这个问题,现在让我们一起来了解其中的原因和解决方案。

出问题的gif

180x180.gif

读取gif的代码

    @PostMapping("/file/gif/upload")
    public String uploadGif(HttpServletRequest request, @RequestParam("file") MultipartFile file) throws IOException {
         // 使用ImageIO读取gif获取上传图片的宽和高
        BufferedImage sourceImage = ImageIO.read(file.getInputStream());
        int sourceWidth = sourceImage.getWidth();// 上传图片的宽度
        int sourceHeight = sourceImage.getHeight();// 上传图片的高度
        log.info("上传图片的宽度:{},上传图片的高度:{}",sourceWidth,sourceHeight);
        //图片宽度和高度校验逻辑
        if(sourceWidth != 180 && sourceHeight != 180){
            return "兄弟,别乱传图片";
        }
        //图片上传fastdfs 并返回地址
        return dfsService.uploadFile(file);
    }

程序上传gif读取文件的代码BufferedImage sourceImage = ImageIO.read(file.getInputStream()); 会报ArrayIndexOutOfBoundsException: 4096异常,具体异常信息如下:

11:02:48.730 [http-nio-8180-exec-4] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - [log,175] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.ArrayIndexOutOfBoundsException: 4096] with root cause
java.lang.ArrayIndexOutOfBoundsException: 4096
    at com.sun.imageio.plugins.gif.GIFImageReader.read(GIFImageReader.java:984)
    at javax.imageio.ImageIO.read(ImageIO.java:1448)
    at javax.imageio.ImageIO.read(ImageIO.java:1352)
    at cn.xj.file.controller.FileController.uploadGif(FileController.java:48)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)

异常原因

这个异常的根本原因在于GIF图像格式的特殊性。GIF(Graphics Interchange Format)是一种广泛使用的图像文件格式,它支持多帧动画和透明背景。然而,某些GIF图像使用了非标准的或不常见的压缩算法,或者包含了复杂的图像帧间数据。由于这些非标准特性,JDK 6~8中的GIFImageReader在解析这些特殊GIF图像时会遇到问题,从而导致数组索引越界的异常。

解决方案

方案一:重新压缩下图片(临时处理快捷、简便)

我们可以采用Photoshop重新保存下或者使用压缩工具压缩下gif就可以了

我们生产环境运营的时间较长了,修改代码验证代价较高,问题出现频率较低(3年出现了2次),所以我们采用的是这种处理方式

Photoshop重新保存之后可正常读取的gif

180x180new.gif

我们可以比对下前后两张图片的属性,正常图片知识大小稍微增加了点

_20230723111838.png

方案二:使用更现代的图像处理库,更换gif读取的方式(一劳永逸)

我们可以在代码中使用别的gif处理库读取gif,示例代码使用的是hutool工具类GifDecoder读取的

    @PostMapping("/file/gif/upload1")
    public String uploadGif1(HttpServletRequest request, @RequestParam("file") MultipartFile file) throws IOException {
        // 使用hutool工具类GifDecoder读取gif获取上传图片的宽和高
        GifDecoder gifDecoder = new GifDecoder();
        gifDecoder.read(file.getInputStream());
        BufferedImage sourceImage = gifDecoder.getImage();
        int sourceWidth = sourceImage.getWidth();// 上传图片的宽度
        int sourceHeight = sourceImage.getHeight();// 上传图片的高度
        log.info("上传图片的宽度:{},上传图片的高度:{}",sourceWidth,sourceHeight);
        //图片宽度和高度校验逻辑
        if(sourceWidth != 180 || sourceHeight != 180){
            return "兄弟,别乱传gif";
        }
        //图片上传fastdfs 并返回地址
        return dfsService.uploadFile(file);
    }

方案三:升级jdk到9及以上(自己玩玩)

哪有企业随便升级这玩意啊,自己本地可以尝试下

结论

在JDK 6~8版本中,ArrayIndexOutOfBoundsException: 4096异常是一个常见而又让人烦恼的问题。然而,通过升级JDK版本、使用现代的图像处理库,以及对特定图像进行处理,我们可以有效地解决这个问题。同时,我们也应该注意检查图像文件的完整性,确保我们处理的是正确的、非损坏的图像文件。

希望本文对解决ArrayIndexOutOfBoundsException: 4096异常问题有所帮助。随着Java技术的不断发展,我们相信Java开发将变得更加轻松和愉快。感谢大家的阅读!如果您有任何问题或想法,请在评论中与我们分享。谢谢!

目录
相关文章
|
Java API 图形学
JAVA读取EMF文件并转化为PNG,JPG,GIF格式
JAVA读取EMF文件并转化为PNG,JPG,GIF格式 使用第三方库下载地址为:http://java.freehep.org/vectorgraphics/index.html 主要思路: 使用EMFInputStream读取EMF文件,然后使用EMFRenderer对象将EMF绘制到创建 好的空白的BufferedImage里面。
1992 0
|
4月前
gstreamer的I420转jpeg格式数据产生耗时
gstreamer的I420转jpeg格式数据产生耗时
|
4月前
gstreamer将RTSP转jpg图片保存
gstreamer将RTSP转jpg图片保存
|
6月前
webp批量转换为png、jpg工具
webp批量转换为png、jpg工具
|
10月前
ENVI_IDL:(批量处理)如何对HDF5文件进行GLT文件的创建并进行几何校正最终输出为IMG格式?
ENVI_IDL:(批量处理)如何对HDF5文件进行GLT文件的创建并进行几何校正最终输出为IMG格式?
100 0
|
10月前
|
数据处理 Windows
成信大ENVI_IDL第二周课堂内容:打开HDF4文件并读取文件以及简单的数据处理和保存+详细解析
成信大ENVI_IDL第二周课堂内容:打开HDF4文件并读取文件以及简单的数据处理和保存+详细解析
257 1
RGB数据剪切后保存为JPG格式文件的代码(使用jpeglib)
RGB数据剪切后保存为JPG格式文件的代码(使用jpeglib)
140 0
测试通过的C代码:平台无关的RGB保存为BMP格式的图片
测试通过的C代码:平台无关的RGB保存为BMP格式的图片
75 0
|
存储 编解码 缓存
Hi3516开发笔记(十):Qt从VPSS中获取通道图像数据存储为jpg文件
上一篇已经将himpp套入qt的基础上进行开发。那么qt中拿到frame则是很关键的交互,这是qt与海思可能编解码交叉开发的关键步骤。
Hi3516开发笔记(十):Qt从VPSS中获取通道图像数据存储为jpg文件
Qt实用技巧:测试QImage加载解码、QImage使用原数据、QImage格式转换等等的时间消耗
Qt实用技巧:测试QImage加载解码、QImage使用原数据、QImage格式转换等等的时间消耗