WebP等特殊格式图片转换Image异常处理复盘

线上问题表象:

有员工发电子签发不出去

问题排查:

原因是用户的头像本身是WebP格式,但是用户为了能把图片上传,把后缀改成了.png,实际文件还是WebP格式。在发电子签的时候,其中的一个pdf需要把用户头像填充进去,但是当前系统不支持WebP图像。

 

WebP 是一种由 ​Google​​ 开发的现代图像格式,旨在通过高效压缩技术减小文件体积,同时保持较高的图像质量。

排查记录:

判断图片实际格式的方式:

1、看文件头

2、代码判断

用户头像的16进制格式:

问题解决思路:

最优方案是用户无感知,后台转换图片,因为让用户不上传XXX格式的图片,对用户体验是很不好的,而且很多用户根本不会转换图片,或者因为手机转格式并不方便。

如果无法后台转,再考虑限制用户上传的方案。

实际解决过程:

排查到的问题的原代码:

1 pic_image = Image.getInstance(IOStreamUtils.inputstream2Bytes(IOStreamUtils.getPhotoInputStream(userVo.getStaffPhoto())));

 

写到一起了,拆一下

1 InputStream photoInputStream = IOStreamUtils.getPhotoInputStream(staffPhoto);
2 byte[] imgb = IOStreamUtils.inputstream2Bytes(photoInputStream);
3 pic_image = Image.getInstance(imgb);

 

调试发现是第3步出的问题,经反复搜索、调试、排查后

最终方案:

1、扩展 TwelveMonkeys 依赖,添加第三方库

若需支持更多格式(如 TIFF、WebP),引入 TwelveMonkeys ImageIO 等插件:

        <dependency>
            <groupId>com.twelvemonkeys.imageio</groupId>
            <artifactId>imageio-jpeg</artifactId>
            <version>${imageio-version}</version>
        </dependency>
        <!-- WebP 支持 -->
        <dependency>
            <groupId>com.twelvemonkeys.imageio</groupId>
            <artifactId>imageio-webp</artifactId>
            <version>${imageio-version}</version>
        </dependency>
        <!-- TIFF 支持 -->
        <dependency>
            <groupId>com.twelvemonkeys.imageio</groupId>
            <artifactId>imageio-tiff</artifactId>
            <version>${imageio-version}</version>
        </dependency>

 

TwelveMonkeys 的插件会自动注册到 ImageIO,无需额外代码

2、优先使用 ImageIO 读取图像,避免直接传递字节数组
String downloadUrl = ossService.getDownloadUrl(staffPhoto);
BufferedImage img = ImageIO.read(new URL(downloadUrl));
if (img != null) {
  // 通过 BufferedImage 创建 iText Image
  pic_image = Image.getInstance(img, null);  
}

 

Image.getInstance() 内部可能依赖 ImageIO 的解析能力。建议先通过 ImageIO.read() 验证是否支持目标格式

 

iText 的 Image.getInstance(byte[] bytes) 方法对格式支持有限,建议改用文件路径或 BufferedImage 初始化

 

至此,问题解决!

 

 

posted on 2025-05-23 16:00  减肥少年  阅读(121)  评论(0)    收藏  举报