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

目录
相关文章
|
3月前
|
Python
用 Python 读取照片的 Exif 信息(顺便说说本人的一些想法)
用 Python 读取照片的 Exif 信息(顺便说说本人的一些想法)
115 2
|
3月前
|
缓存 应用服务中间件 网络安全
PbootCMS增加可允许上传文件类型,例如webp、mov等文件格式扩展
PbootCMS增加可允许上传文件类型,例如webp、mov等文件格式扩展
|
7月前
|
图形学
【unity小技巧】unity读excel配置表操作,excel转txt文本,并读取txt文本内容,实例说明
【unity小技巧】unity读excel配置表操作,excel转txt文本,并读取txt文本内容,实例说明
244 0
|
7月前
|
Java
JAVA读取EMF文件并转化为PNG,JPG,GIF格式
JAVA读取EMF文件并转化为PNG,JPG,GIF格式
379 0
|
8月前
分享:批量多目录图片如何转换PDF,一次性转换多级目录批量的PDF的转换,合并,输出另存等问题,图片转PDF文件,批量图片转PDF文件,多级目录的图片转PDF文件,并且保存到不同的地方,全部搞定
本文介绍了如何高效地将图片转换为PDF,包括单张、多张及多级目录下的图片转换和合并。提供了软件下载链接(百度网盘、腾讯云盘),软件操作简便,支持保存原目录或自定义新目录。转换选项包括单个文件、多个文件夹单独转换以及合并转换。用户可通过双击路径访问源图片和转换结果。该工具特别解决了多级目录图片批量转换的难题,实现保存地址的自由设定,满足不同业务需求。
463 0
|
8月前
|
编解码 API 计算机视觉
opencv从视频文件读取视频内容,从摄像头读取保存视频内容
opencv从视频文件读取视频内容,从摄像头读取保存视频内容
|
8月前
|
Java
Java PDF 相关 1、拷贝多个PDF到一个PDF,并且文件大小变小,文本等信息保留
1、合并多个PDF,并且文件变小,后面添加的文本信息保留
163 0
|
8月前
gstreamer的I420转jpeg格式数据产生耗时
gstreamer的I420转jpeg格式数据产生耗时
|
图形学
Qt&Vtk-003-读取jpg、png、dicom等格式图片
本文其实才能算是真正的Qt与Vtk结合,具体实现JPG、PNG、TIFF、DICOM、BMP及一个3D Cube显示。
700 1
Qt&Vtk-003-读取jpg、png、dicom等格式图片