From 89b37907e757223f3fda907961b0e5348bcea109 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8D=92?= Date: Mon, 3 Nov 2025 15:26:52 +0800 Subject: [PATCH] 1 --- doc/图片转换功能说明.md | 8 +- pom.xml | 18 ++- .../business/service/ImageConvertService.java | 112 ++++++++++-------- 3 files changed, 84 insertions(+), 54 deletions(-) diff --git a/doc/图片转换功能说明.md b/doc/图片转换功能说明.md index 6c630ea..4db8959 100644 --- a/doc/图片转换功能说明.md +++ b/doc/图片转换功能说明.md @@ -66,7 +66,13 @@ image: 项目已添加以下依赖: 1. **Thumbnailator** (0.4.20):图片处理库 -2. **webp-imageio** (0.1.0):WebP格式支持库 + +**注意**:WebP格式支持需要系统或JVM本身支持webp格式。如果系统不支持webp,转换功能会跳过webp图片并返回原URL,不会影响系统正常运行。 + +如需支持webp格式转换,可以: +- 使用支持webp的JVM版本 +- 手动添加webp-imageio库到项目中 +- 使用其他webp解码库 ## API接口 diff --git a/pom.xml b/pom.xml index 8e2d544..a591f90 100644 --- a/pom.xml +++ b/pom.xml @@ -119,12 +119,6 @@ thumbnailator 0.4.20 - - - com.github.gotson - webp-imageio - 0.1.0 - @@ -170,5 +164,17 @@ RocketMQ Repository https://repo1.maven.org/maven2/org/apache/rocketmq/ + + + central + Maven Central Repository + https://repo1.maven.org/maven2 + + true + + + false + + diff --git a/src/main/java/cn/van/business/service/ImageConvertService.java b/src/main/java/cn/van/business/service/ImageConvertService.java index 386db69..41b34cd 100644 --- a/src/main/java/cn/van/business/service/ImageConvertService.java +++ b/src/main/java/cn/van/business/service/ImageConvertService.java @@ -10,12 +10,15 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import net.coobird.thumbnailator.Thumbnails; import javax.imageio.ImageIO; import javax.imageio.ImageReader; import javax.imageio.stream.ImageInputStream; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -23,35 +26,37 @@ import java.time.LocalDateTime; import java.util.*; /** - * WebP图片IO支持 - * 注册WebP图片格式的读写器 + * WebP图片IO支持工具类 + * 尝试使用可用的方式读取webp图片 */ class WebPImageIO { private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(WebPImageIO.class); - private static volatile boolean initialized = false; + private static volatile boolean webpSupported = false; + private static volatile boolean checked = false; /** - * 初始化WebP支持 - * webp-imageio库在类加载时会通过ServiceLoader自动注册到ImageIO + * 检查是否支持webp格式 */ - static synchronized void init() { - if (initialized) { - return; + static synchronized boolean isWebPSupported() { + if (checked) { + return webpSupported; } - // 检查是否支持webp格式 try { Iterator readers = ImageIO.getImageReadersByFormatName("webp"); - if (readers.hasNext()) { - log.debug("WebP图片格式支持已启用"); + webpSupported = readers.hasNext(); + if (webpSupported) { + log.info("WebP图片格式支持已启用"); } else { - log.warn("未检测到WebP图片格式支持,webp转换可能失败。请确认webp-imageio依赖已正确加载"); + log.warn("未检测到WebP图片格式支持,webp图片转换将被跳过"); } } catch (Exception e) { log.warn("检查WebP支持时出错: {}", e.getMessage()); + webpSupported = false; } - initialized = true; + checked = true; + return webpSupported; } } @@ -102,8 +107,8 @@ public class ImageConvertService { String convertedUrl = convertImageUrl(imageUrl); convertedUrls.add(convertedUrl); } catch (Exception e) { - log.warn("图片转换失败,使用原URL: {}, 错误: {}", imageUrl, e.getMessage()); - // 转换失败时使用原URL + // 转换失败时使用原URL,不中断流程 + log.warn("图片转换失败,使用原URL: {}. 错误: {}", imageUrl, e.getMessage()); convertedUrls.add(imageUrl); } } @@ -116,8 +121,9 @@ public class ImageConvertService { * * @param originalUrl 原始图片URL * @return 转换后的图片URL(如果不需要转换则返回原URL) + * @throws Exception 转换过程中的异常(调用方会捕获并返回原URL) */ - private String convertImageUrl(String originalUrl) { + private String convertImageUrl(String originalUrl) throws Exception { if (StrUtil.isBlank(originalUrl)) { return originalUrl; } @@ -127,6 +133,12 @@ public class ImageConvertService { return originalUrl; } + // 检查系统是否支持webp转换 + if (!WebPImageIO.isWebPSupported()) { + log.debug("系统不支持webp格式,跳过转换: {}", originalUrl); + throw new IOException("系统不支持webp格式转换"); + } + // 检查是否已转换 Optional existing = imageConversionRepository.findByOriginalUrl(originalUrl); if (existing.isPresent()) { @@ -136,14 +148,9 @@ public class ImageConvertService { } // 执行转换 - try { - String convertedUrl = performConversion(originalUrl); - log.info("图片转换成功: {} -> {}", originalUrl, convertedUrl); - return convertedUrl; - } catch (Exception e) { - log.error("图片转换失败: {}, 错误: {}", originalUrl, e.getMessage(), e); - throw e; - } + String convertedUrl = performConversion(originalUrl); + log.info("图片转换成功: {} -> {}", originalUrl, convertedUrl); + return convertedUrl; } /** @@ -202,34 +209,45 @@ public class ImageConvertService { // 转换图片格式 BufferedImage bufferedImage = null; try { - // 初始化WebP支持 - WebPImageIO.init(); + // 检查是否支持webp格式 + boolean webpSupported = WebPImageIO.isWebPSupported(); - // 尝试使用ImageIO读取 - BufferedImage tempImage = null; - try (ByteArrayInputStream bais = new ByteArrayInputStream(imageData)) { - tempImage = ImageIO.read(bais); - } - - if (tempImage != null) { - bufferedImage = tempImage; - } else { - // 如果ImageIO无法读取,尝试使用WebP特定的读取器 - Iterator readers = ImageIO.getImageReadersByFormatName("webp"); - if (readers.hasNext()) { - ImageReader reader = readers.next(); - try (ByteArrayInputStream bais = new ByteArrayInputStream(imageData); - ImageInputStream iis = ImageIO.createImageInputStream(bais)) { - reader.setInput(iis); - bufferedImage = reader.read(0); - } finally { - reader.dispose(); - } + if (webpSupported) { + // 如果支持webp,尝试使用ImageIO读取 + try (ByteArrayInputStream bais = new ByteArrayInputStream(imageData)) { + bufferedImage = ImageIO.read(bais); } + // 如果ImageIO无法读取,尝试使用WebP特定的读取器 if (bufferedImage == null) { - throw new IOException("无法读取webp图片格式,请确认已添加webp-imageio依赖"); + Iterator readers = ImageIO.getImageReadersByFormatName("webp"); + if (readers.hasNext()) { + ImageReader reader = readers.next(); + try (ByteArrayInputStream bais = new ByteArrayInputStream(imageData); + ImageInputStream iis = ImageIO.createImageInputStream(bais)) { + reader.setInput(iis); + bufferedImage = reader.read(0); + } finally { + reader.dispose(); + } + } } + } else { + // 如果不支持webp,尝试使用Thumbnailator转换 + // 注意:Thumbnailator内部也使用ImageIO,所以通常也无法处理webp + try (ByteArrayInputStream bais = new ByteArrayInputStream(imageData)) { + bufferedImage = Thumbnails.of(bais) + .scale(1.0) + .asBufferedImage(); + } catch (Exception e) { + log.debug("Thumbnailator无法读取webp图片: {}", e.getMessage()); + // 如果无法转换,抛出异常,后续会返回原URL + throw new IOException("当前系统不支持webp格式转换。图片将保持原格式返回。", e); + } + } + + if (bufferedImage == null) { + throw new IOException("无法读取webp图片格式。当前系统不支持webp格式转换。"); } // 如果是RGBA格式,转换为RGB