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初始化
至此,问题解决!
浙公网安备 33010602011771号