feat(watermark): 添加打印水印功能支持

- 在WatermarkConfig中添加竖版和横版打印水印URL列表配置
- 将打印水印URL列表传递给WatermarkStage处理
- 在PrinterDefaultWatermarkTemplateBuilder中实现打印水印叠加层功能
- 添加resolvePrintWatermarkUrl方法根据图片方向选择对应URL
- 在WatermarkRequest和WatermarkInfo中添加打印水印相关字段
- 从配置文件读取打印水印URL列表并构建到WatermarkConfig中
This commit is contained in:
2026-02-12 20:10:34 +08:00
parent dee504f7ed
commit 9cfb366839
7 changed files with 72 additions and 0 deletions

View File

@@ -7,6 +7,7 @@ import lombok.Builder;
import lombok.Getter; import lombok.Getter;
import java.io.File; import java.io.File;
import java.util.List;
/** /**
* 水印Stage配置 * 水印Stage配置
@@ -67,4 +68,16 @@ public class WatermarkConfig {
*/ */
@Builder.Default @Builder.Default
private final long edgeTimeoutMs = 10_000L; private final long edgeTimeoutMs = 10_000L;
/**
* 打印水印竖版URL列表
* 用于在竖屏图片上添加全屏水印叠加层(在原图上方,文字/二维码下方)
*/
private final List<String> printWatermarkPUrlList;
/**
* 打印水印横版URL列表
* 用于在横屏图片上添加全屏水印叠加层(在原图上方,文字/二维码下方)
*/
private final List<String> printWatermarkLUrlList;
} }

View File

@@ -241,6 +241,10 @@ public class WatermarkStage extends AbstractPipelineStage<PhotoProcessContext> {
} }
} }
// 传递打印水印URL列表(横竖版由边缘端根据图片实际尺寸判断)
info.setPrintWatermarkPUrlList(config.getPrintWatermarkPUrlList());
info.setPrintWatermarkLUrlList(config.getPrintWatermarkLUrlList());
return info; return info;
} }
} }

View File

@@ -77,6 +77,18 @@ public class PrinterDefaultWatermarkTemplateBuilder extends AbstractWatermarkTem
elements.add(originalImageElement); elements.add(originalImageElement);
dynamicData.put("originalImage", request.getOriginalImageUrl()); dynamicData.put("originalImage", request.getOriginalImageUrl());
// 0.5 打印水印叠加层(z-index=5,全屏覆盖,在原图上方、文字/二维码下方)
if (request.getPrintWatermarkUrl() != null && !request.getPrintWatermarkUrl().isEmpty()) {
PuzzleElementEntity printWatermarkElement = createImageElement(
"printWatermark", "打印水印",
0, 0,
imageWidth, imageHeight, 5,
FIT_MODE_COVER, null, null
);
elements.add(printWatermarkElement);
dynamicData.put("printWatermark", request.getPrintWatermarkUrl());
}
// 计算二维码位置 // 计算二维码位置
int qrcodeWidth = scaledQrcodeSize; int qrcodeWidth = scaledQrcodeSize;
int qrcodeHeight = scaledQrcodeSize; int qrcodeHeight = scaledQrcodeSize;

View File

@@ -21,6 +21,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL; import java.net.URL;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.UUID; import java.util.UUID;
/** /**
@@ -237,6 +238,8 @@ public class WatermarkEdgeService {
.offsetRight(info.getOffsetRight()) .offsetRight(info.getOffsetRight())
.offsetTop(info.getOffsetTop()) .offsetTop(info.getOffsetTop())
.offsetBottom(info.getOffsetBottom()) .offsetBottom(info.getOffsetBottom())
.printWatermarkUrl(resolvePrintWatermarkUrl(imageWidth, imageHeight,
info.getPrintWatermarkPUrlList(), info.getPrintWatermarkLUrlList()))
.outputFormat(type.getPreferFileType().equalsIgnoreCase("png") ? "PNG" : "JPEG") .outputFormat(type.getPreferFileType().equalsIgnoreCase("png") ? "PNG" : "JPEG")
.outputQuality(90) .outputQuality(90)
.build(); .build();
@@ -294,6 +297,25 @@ public class WatermarkEdgeService {
}; };
} }
/**
* 根据图片方向从URL列表中选取对应的打印水印URL
*
* @param imageWidth 图片宽度
* @param imageHeight 图片高度
* @param pUrlList 竖版URL列表
* @param lUrlList 横版URL列表
* @return 选中的URL,无可用URL时返回null
*/
private String resolvePrintWatermarkUrl(int imageWidth, int imageHeight,
List<String> pUrlList, List<String> lUrlList) {
boolean isLandscape = imageWidth >= imageHeight;
List<String> urlList = isLandscape ? lUrlList : pUrlList;
if (urlList != null && !urlList.isEmpty()) {
return urlList.get(0);
}
return null;
}
/** /**
* 获取图片尺寸 * 获取图片尺寸
* *

View File

@@ -70,6 +70,12 @@ public class WatermarkRequest {
@Builder.Default @Builder.Default
private Integer outputQuality = 75; private Integer outputQuality = 75;
/**
* 打印水印URL(根据图片方向已解析的单个URL)
* 用于在原图上方、文字/二维码下方添加全屏水印叠加层
*/
private String printWatermarkUrl;
public double getScaleValue() { public double getScaleValue() {
return scale != null ? scale : 1.0; return scale != null ? scale : 1.0;
} }

View File

@@ -5,6 +5,7 @@ import lombok.Data;
import java.io.File; import java.io.File;
import java.util.Date; import java.util.Date;
import java.util.List;
@Data @Data
public class WatermarkInfo { public class WatermarkInfo {
@@ -40,6 +41,16 @@ public class WatermarkInfo {
*/ */
private Double scale; private Double scale;
/**
* 打印水印竖版URL列表
*/
private List<String> printWatermarkPUrlList;
/**
* 打印水印横版URL列表
*/
private List<String> printWatermarkLUrlList;
public String getDatetimeLine() { public String getDatetimeLine() {
if (datetimeLine == null) { if (datetimeLine == null) {
datetimeLine = DateUtil.format(datetime, dtFormat); datetimeLine = DateUtil.format(datetime, dtFormat);

View File

@@ -1084,6 +1084,8 @@ public class PrinterServiceImpl implements PrinterService {
String scenicText = scenicConfig.getString("print_watermark_scenic_text", ""); String scenicText = scenicConfig.getString("print_watermark_scenic_text", "");
String dateFormat = scenicConfig.getString("print_watermark_dt_format", "yyyy.MM.dd"); String dateFormat = scenicConfig.getString("print_watermark_dt_format", "yyyy.MM.dd");
List<String> printWatermarkPUrlList = scenicConfig.getList("print_watermark_p_url", String.class);
List<String> printWatermarkLUrlList = scenicConfig.getList("print_watermark_l_url", String.class);
return WatermarkConfig.builder() return WatermarkConfig.builder()
.watermarkType(watermarkType) .watermarkType(watermarkType)
@@ -1094,6 +1096,8 @@ public class PrinterServiceImpl implements PrinterService {
.edgeEnabled(true) .edgeEnabled(true)
.qrcodeFile(qrCodeFile) .qrcodeFile(qrCodeFile)
.scale(scale) .scale(scale)
.printWatermarkPUrlList(printWatermarkPUrlList)
.printWatermarkLUrlList(printWatermarkLUrlList)
.build(); .build();
} }