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开发将变得更加轻松和愉快。感谢大家的阅读!如果您有任何问题或想法,请在评论中与我们分享。谢谢!

目录
相关文章
|
8月前
|
Java
JAVA读取EMF文件并转化为PNG,JPG,GIF格式
JAVA读取EMF文件并转化为PNG,JPG,GIF格式
395 0
|
9月前
|
编解码 API 计算机视觉
opencv从视频文件读取视频内容,从摄像头读取保存视频内容
opencv从视频文件读取视频内容,从摄像头读取保存视频内容
成信大ENVI_IDL第三周课堂内容1:读取OMI数据(HDF5文件)以及输出+解析
成信大ENVI_IDL第三周课堂内容1:读取OMI数据(HDF5文件)以及输出+解析
208 0
|
9月前
|
数据安全/隐私保护 Python
Python办公自动化【Word转换PDF、PDF读取内容、PDF合并文件、PDF拆分文件、PDF加密文件、PPT基本操作-增加幻灯片、增加内容】(六)-全面详解(学习总结---从入门到深化)(下)
Python办公自动化【Word转换PDF、PDF读取内容、PDF合并文件、PDF拆分文件、PDF加密文件、PPT基本操作-增加幻灯片、增加内容】(六)-全面详解(学习总结---从入门到深化)
100 1
|
9月前
|
Java
Java PDF 相关 1、拷贝多个PDF到一个PDF,并且文件大小变小,文本等信息保留
1、合并多个PDF,并且文件变小,后面添加的文本信息保留
177 0
|
9月前
|
数据安全/隐私保护 Python Windows
Python办公自动化【Word转换PDF、PDF读取内容、PDF合并文件、PDF拆分文件、PDF加密文件、PPT基本操作-增加幻灯片、增加内容】(六)-全面详解(学习总结---从入门到深化)(上)
Python办公自动化【Word转换PDF、PDF读取内容、PDF合并文件、PDF拆分文件、PDF加密文件、PPT基本操作-增加幻灯片、增加内容】(六)-全面详解(学习总结---从入门到深化)
150 0
|
9月前
gstreamer的I420转jpeg格式数据产生耗时
gstreamer的I420转jpeg格式数据产生耗时
ENVI_IDL:(批量处理)如何对HDF5文件进行GLT文件的创建并进行几何校正最终输出为IMG格式?
ENVI_IDL:(批量处理)如何对HDF5文件进行GLT文件的创建并进行几何校正最终输出为IMG格式?
205 0
|
数据处理 Windows
成信大ENVI_IDL第二周课堂内容:打开HDF4文件并读取文件以及简单的数据处理和保存+详细解析
成信大ENVI_IDL第二周课堂内容:打开HDF4文件并读取文件以及简单的数据处理和保存+详细解析
439 1
|
Python
tinytag-用于读取MP3,OGG,FLAC和Wave文件的音乐元数据的python库
tinytag是一个python库,用于使用python读取MP3,OGG,OPUS,MP4,M4A,FLAC,WMA和Wave文件的音乐元数据。特征: - 读取音频文件的标签,长度和封面图像 - 支持的格式:(MP3 (ID3 v1, v1.1, v2.2, v2.3+)、Wave/RIFF、OGG、OPUS、FLAC、WMA、MP4/M4A/M4B) - 纯python,无依赖 - 支持python 2.7和3.4或更高版本 - 高测试覆盖率 - 仅几百行代码(只需将其包含在您的项目中即可!)
1998 0
tinytag-用于读取MP3,OGG,FLAC和Wave文件的音乐元数据的python库