You've already forked FrameTour-BE
feat(watermark): 添加边缘端水印处理功能
- 引入 WatermarkEdgeService 支持边缘端渲染 - 在 WatermarkConfig 中添加边缘端相关配置参数 - 在 WatermarkStage 中实现边缘端处理逻辑和降级机制 - 修改 ImageWatermarkOperatorEnum 的默认输出格式为 jpg - 移除已废弃的 DefaultImageWatermarkOperator 类 - 更新 GoodsServiceImpl 使用边缘端处理水印 - 优化 PuzzleEdgeWorkerIpInterceptor 允许本地回环地址访问 - 修正 PrinterDefaultWatermarkTemplateBuilder 样式常量名称
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package com.ycwl.basic.image.pipeline.stages;
|
||||
|
||||
import com.ycwl.basic.image.watermark.edge.WatermarkEdgeService;
|
||||
import com.ycwl.basic.image.watermark.enums.ImageWatermarkOperatorEnum;
|
||||
import com.ycwl.basic.storage.adapters.IStorageAdapter;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@@ -41,4 +43,28 @@ public class WatermarkConfig {
|
||||
*/
|
||||
@Builder.Default
|
||||
private final Double scale = 1.0;
|
||||
|
||||
/**
|
||||
* 边缘端水印服务(可选)
|
||||
* 如果设置,将优先尝试使用边缘端处理
|
||||
*/
|
||||
private final WatermarkEdgeService edgeService;
|
||||
|
||||
/**
|
||||
* 存储适配器(边缘端处理时需要)
|
||||
* 用于上传原图和二维码到临时位置
|
||||
*/
|
||||
private final IStorageAdapter storageAdapter;
|
||||
|
||||
/**
|
||||
* 是否启用边缘端处理
|
||||
*/
|
||||
@Builder.Default
|
||||
private final boolean edgeEnabled = false;
|
||||
|
||||
/**
|
||||
* 边缘端处理超时时间(毫秒)
|
||||
*/
|
||||
@Builder.Default
|
||||
private final long edgeTimeoutMs = 30000L;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.ycwl.basic.image.pipeline.stages;
|
||||
import com.ycwl.basic.image.pipeline.core.PhotoProcessContext;
|
||||
import com.ycwl.basic.image.pipeline.enums.ImageType;
|
||||
import com.ycwl.basic.image.watermark.ImageWatermarkFactory;
|
||||
import com.ycwl.basic.image.watermark.edge.WatermarkEdgeService;
|
||||
import com.ycwl.basic.image.watermark.entity.WatermarkInfo;
|
||||
import com.ycwl.basic.image.watermark.enums.ImageWatermarkOperatorEnum;
|
||||
import com.ycwl.basic.image.watermark.operator.IOperator;
|
||||
@@ -10,6 +11,7 @@ import com.ycwl.basic.pipeline.annotation.StageConfig;
|
||||
import com.ycwl.basic.pipeline.core.AbstractPipelineStage;
|
||||
import com.ycwl.basic.pipeline.core.StageResult;
|
||||
import com.ycwl.basic.pipeline.enums.StageOptionalMode;
|
||||
import com.ycwl.basic.storage.adapters.IStorageAdapter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@@ -21,6 +23,7 @@ import java.util.List;
|
||||
/**
|
||||
* 水印处理Stage
|
||||
* 支持三级降级: 配置的水印类型 -> PRINTER_DEFAULT -> 无水印
|
||||
* 支持边缘端渲染(可选)
|
||||
*/
|
||||
@Slf4j
|
||||
@StageConfig(
|
||||
@@ -127,6 +130,19 @@ public class WatermarkStage extends AbstractPipelineStage<PhotoProcessContext> {
|
||||
File watermarkedFile = context.getTempFileManager()
|
||||
.createTempFile("watermark_" + type.getType(), "." + fileExt);
|
||||
|
||||
// 尝试边缘端处理
|
||||
if (shouldUseEdgeProcessing(type)) {
|
||||
File edgeResult = tryEdgeProcessing(context, type, currentFile, watermarkedFile);
|
||||
if (edgeResult != null && edgeResult.exists()) {
|
||||
context.updateProcessedFile(edgeResult);
|
||||
log.info("边缘端水印应用成功: type={}, size={}KB", type.getType(), edgeResult.length() / 1024);
|
||||
return StageResult.success(String.format("水印(边缘端): %s (%dKB)",
|
||||
type.getType(), edgeResult.length() / 1024));
|
||||
}
|
||||
log.warn("边缘端水印处理失败,降级到本地处理: type={}", type.getType());
|
||||
}
|
||||
|
||||
// 本地处理(降级或直接使用)
|
||||
WatermarkInfo watermarkInfo = buildWatermarkInfo(context, currentFile, watermarkedFile, type);
|
||||
|
||||
IOperator operator = ImageWatermarkFactory.get(type);
|
||||
@@ -143,6 +159,46 @@ public class WatermarkStage extends AbstractPipelineStage<PhotoProcessContext> {
|
||||
type.getType(), result.length() / 1024));
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否应使用边缘端处理
|
||||
*/
|
||||
private boolean shouldUseEdgeProcessing(ImageWatermarkOperatorEnum type) {
|
||||
if (!config.isEdgeEnabled()) {
|
||||
return false;
|
||||
}
|
||||
WatermarkEdgeService edgeService = config.getEdgeService();
|
||||
if (edgeService == null) {
|
||||
return false;
|
||||
}
|
||||
IStorageAdapter storageAdapter = config.getStorageAdapter();
|
||||
return storageAdapter != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 尝试使用边缘端处理
|
||||
*
|
||||
* @return 处理后的文件,失败返回 null
|
||||
*/
|
||||
private File tryEdgeProcessing(PhotoProcessContext context,
|
||||
ImageWatermarkOperatorEnum type,
|
||||
File currentFile,
|
||||
File watermarkedFile) {
|
||||
try {
|
||||
WatermarkEdgeService edgeService = config.getEdgeService();
|
||||
IStorageAdapter storageAdapter = config.getStorageAdapter();
|
||||
|
||||
// 构建水印信息用于边缘端处理
|
||||
WatermarkInfo info = buildWatermarkInfo(context, currentFile, watermarkedFile, type);
|
||||
|
||||
// 调用边缘端服务处理
|
||||
return edgeService.processWatermarkFromFile(info, type, storageAdapter);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("边缘端水印处理异常: type={}, error={}", type.getType(), e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建水印参数
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user