You've already forked FrameTour-BE
feat(image): 启用边缘端水印处理并优化徕卡模板布局算法
- 将边缘端处理默认启用状态从false改为true - 将边缘端处理超时时间从30秒调整为10秒 - 将徕卡水印模板的固定像素配置转换为基于1920x1080的百分比配置 - 新增多种百分比常量包括底部区域、Logo大小、边距、字体大小等 - 实现动态计算实际像素值的方法替代固定数值 - 在PrinterServiceImpl中注入WatermarkEdgeService依赖 - 配置水印处理流程启用边缘服务和存储适配器
This commit is contained in:
@@ -60,11 +60,11 @@ public class WatermarkConfig {
|
|||||||
* 是否启用边缘端处理
|
* 是否启用边缘端处理
|
||||||
*/
|
*/
|
||||||
@Builder.Default
|
@Builder.Default
|
||||||
private final boolean edgeEnabled = false;
|
private final boolean edgeEnabled = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 边缘端处理超时时间(毫秒)
|
* 边缘端处理超时时间(毫秒)
|
||||||
*/
|
*/
|
||||||
@Builder.Default
|
@Builder.Default
|
||||||
private final long edgeTimeoutMs = 30000L;
|
private final long edgeTimeoutMs = 10_000L;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -190,8 +190,8 @@ public class WatermarkStage extends AbstractPipelineStage<PhotoProcessContext> {
|
|||||||
// 构建水印信息用于边缘端处理
|
// 构建水印信息用于边缘端处理
|
||||||
WatermarkInfo info = buildWatermarkInfo(context, currentFile, watermarkedFile, type);
|
WatermarkInfo info = buildWatermarkInfo(context, currentFile, watermarkedFile, type);
|
||||||
|
|
||||||
// 调用边缘端服务处理
|
// 调用边缘端服务处理,传递 processId 作为 recordId
|
||||||
return edgeService.processWatermarkFromFile(info, type, storageAdapter);
|
return edgeService.processWatermarkFromFile(info, type, storageAdapter, context.getProcessId());
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("边缘端水印处理异常: type={}, error={}", type.getType(), e.getMessage(), e);
|
log.error("边缘端水印处理异常: type={}, error={}", type.getType(), e.getMessage(), e);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import java.util.Map;
|
|||||||
* 徕卡风格水印模板构建器
|
* 徕卡风格水印模板构建器
|
||||||
* 对应 LeicaWatermarkOperator
|
* 对应 LeicaWatermarkOperator
|
||||||
*
|
*
|
||||||
* 布局说明:
|
* 布局说明(百分比基于1920x1080量化,精度0.5%):
|
||||||
* - 画布大小 = 原图大小(不扩展)
|
* - 画布大小 = 原图大小(不扩展)
|
||||||
* - 原图收缩放在画布上半部分,底部留出空间
|
* - 原图收缩放在画布上半部分,底部留出空间
|
||||||
* - 底部白色区域左侧:帧途 Logo + "帧途" 文字
|
* - 底部白色区域左侧:帧途 Logo + "帧途" 文字
|
||||||
@@ -22,20 +22,32 @@ public class LeicaWatermarkTemplateBuilder extends AbstractWatermarkTemplateBuil
|
|||||||
|
|
||||||
public static final String STYLE = "leica";
|
public static final String STYLE = "leica";
|
||||||
|
|
||||||
// 常量配置(与 LeicaWatermarkOperator 保持一致)
|
// 百分比常量配置(基于1920x1080量化,精度0.5%)
|
||||||
private static final int EXTRA_BOTTOM_PX = 140;
|
/** 底部额外区域占高度百分比 */
|
||||||
private static final int LOGO_SIZE = 50;
|
private static final double EXTRA_BOTTOM_PERCENT = 0.13; // 13%
|
||||||
private static final int LOGO_EXTRA_BORDER = 20;
|
/** Logo大小占高度百分比 */
|
||||||
private static final int LOGO_FONT_SIZE = 38;
|
private static final double LOGO_SIZE_PERCENT = 0.045; // 4.5%
|
||||||
|
/** Logo额外边距占高度百分比 */
|
||||||
|
private static final double LOGO_EXTRA_BORDER_PERCENT = 0.02; // 2%
|
||||||
|
/** Logo字体大小占高度百分比 */
|
||||||
|
private static final double LOGO_FONT_SIZE_PERCENT = 0.035; // 3.5%
|
||||||
|
/** 二维码大小占高度百分比 */
|
||||||
|
private static final double QRCODE_SIZE_PERCENT = 0.11; // 11%
|
||||||
|
/** 二维码X偏移占宽度百分比 */
|
||||||
|
private static final double QRCODE_OFFSET_X_PERCENT = 0.005; // 0.5%
|
||||||
|
/** 二维码Y偏移占高度百分比 */
|
||||||
|
private static final double QRCODE_OFFSET_Y_PERCENT = 0.02; // 2%
|
||||||
|
/** 左右边距占宽度百分比 */
|
||||||
|
private static final double OFFSET_X_PERCENT = 0.04; // 4%
|
||||||
|
/** 上下边距占高度百分比 */
|
||||||
|
private static final double OFFSET_Y_PERCENT = 0.03; // 3%
|
||||||
|
/** 景区名字体大小占高度百分比 */
|
||||||
|
private static final double SCENIC_FONT_SIZE_PERCENT = 0.03; // 3%
|
||||||
|
/** 日期时间字体大小占高度百分比 */
|
||||||
|
private static final double DATETIME_FONT_SIZE_PERCENT = 0.025; // 2.5%
|
||||||
|
|
||||||
private static final String LOGO_TEXT_COLOR = "#333333";
|
private static final String LOGO_TEXT_COLOR = "#333333";
|
||||||
private static final int QRCODE_SIZE = 120;
|
|
||||||
private static final int QRCODE_OFFSET_X = 5;
|
|
||||||
private static final int QRCODE_OFFSET_Y = 20;
|
|
||||||
private static final int OFFSET_X = 80;
|
|
||||||
private static final int OFFSET_Y = 30;
|
|
||||||
private static final int SCENIC_FONT_SIZE = 32;
|
|
||||||
private static final String SCENIC_COLOR = "#333333";
|
private static final String SCENIC_COLOR = "#333333";
|
||||||
private static final int DATETIME_FONT_SIZE = 28;
|
|
||||||
private static final String DATETIME_COLOR = "#999999";
|
private static final String DATETIME_COLOR = "#999999";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -53,12 +65,25 @@ public class LeicaWatermarkTemplateBuilder extends AbstractWatermarkTemplateBuil
|
|||||||
int imageWidth = request.getImageWidth();
|
int imageWidth = request.getImageWidth();
|
||||||
int imageHeight = request.getImageHeight();
|
int imageHeight = request.getImageHeight();
|
||||||
|
|
||||||
|
// 根据百分比计算实际像素值
|
||||||
|
int extraBottom = (int) (imageHeight * EXTRA_BOTTOM_PERCENT);
|
||||||
|
int logoSize = (int) (imageHeight * LOGO_SIZE_PERCENT);
|
||||||
|
int logoExtraBorder = (int) (imageHeight * LOGO_EXTRA_BORDER_PERCENT);
|
||||||
|
int logoFontSize = (int) (imageHeight * LOGO_FONT_SIZE_PERCENT);
|
||||||
|
int qrcodeSize = (int) (imageHeight * QRCODE_SIZE_PERCENT);
|
||||||
|
int qrcodeOffsetX = (int) (imageWidth * QRCODE_OFFSET_X_PERCENT);
|
||||||
|
int qrcodeOffsetY = (int) (imageHeight * QRCODE_OFFSET_Y_PERCENT);
|
||||||
|
int offsetX = (int) (imageWidth * OFFSET_X_PERCENT);
|
||||||
|
int offsetY = (int) (imageHeight * OFFSET_Y_PERCENT);
|
||||||
|
int scenicFontSize = (int) (imageHeight * SCENIC_FONT_SIZE_PERCENT);
|
||||||
|
int datetimeFontSize = (int) (imageHeight * DATETIME_FONT_SIZE_PERCENT);
|
||||||
|
|
||||||
// 画布大小 = 原图大小(不扩展)
|
// 画布大小 = 原图大小(不扩展)
|
||||||
int canvasWidth = imageWidth;
|
int canvasWidth = imageWidth;
|
||||||
int canvasHeight = imageHeight;
|
int canvasHeight = imageHeight;
|
||||||
|
|
||||||
// 原图收缩后的区域高度
|
// 原图收缩后的区域高度
|
||||||
int shrunkImageHeight = imageHeight - EXTRA_BOTTOM_PX;
|
int shrunkImageHeight = imageHeight - extraBottom;
|
||||||
// 底部区域起始 Y 坐标
|
// 底部区域起始 Y 坐标
|
||||||
int bottomAreaY = shrunkImageHeight;
|
int bottomAreaY = shrunkImageHeight;
|
||||||
|
|
||||||
@@ -84,47 +109,44 @@ public class LeicaWatermarkTemplateBuilder extends AbstractWatermarkTemplateBuil
|
|||||||
dynamicData.put("originalImage", request.getOriginalImageUrl());
|
dynamicData.put("originalImage", request.getOriginalImageUrl());
|
||||||
|
|
||||||
// 2. Logo 元素(底部左侧)
|
// 2. Logo 元素(底部左侧)
|
||||||
int logoY = bottomAreaY + OFFSET_Y + LOGO_EXTRA_BORDER;
|
int logoY = bottomAreaY + offsetY + logoExtraBorder;
|
||||||
PuzzleElementEntity logoElement = createImageElement(
|
PuzzleElementEntity logoElement = createImageElement(
|
||||||
"logo", "Logo",
|
"logo", "Logo",
|
||||||
OFFSET_X, logoY - 12,
|
offsetX, logoY - (int)(logoSize * 0.24),
|
||||||
LOGO_SIZE, LOGO_SIZE, 10,
|
logoSize, logoSize, 10,
|
||||||
FIT_MODE_CONTAIN, null, null
|
FIT_MODE_CONTAIN, null, null
|
||||||
);
|
);
|
||||||
elements.add(logoElement);
|
elements.add(logoElement);
|
||||||
dynamicData.put("logo", LOGO_URL);
|
dynamicData.put("logo", LOGO_URL);
|
||||||
|
|
||||||
// 3. "帧途" 文字(Logo 右边)
|
// 3. "帧途" 文字(Logo 右边)
|
||||||
int logoTextX = OFFSET_X + LOGO_SIZE + 5;
|
int logoTextX = offsetX + logoSize + (int)(imageWidth * 0.005);
|
||||||
int logoTextY = bottomAreaY + OFFSET_Y + LOGO_EXTRA_BORDER;
|
int logoTextY = bottomAreaY + offsetY + logoExtraBorder;
|
||||||
PuzzleElementEntity logoTextElement = createTextElement(
|
PuzzleElementEntity logoTextElement = createTextElement(
|
||||||
"logoText", "帧途文字",
|
"logoText", "帧途文字",
|
||||||
logoTextX, logoTextY,
|
logoTextX, logoTextY,
|
||||||
100, LOGO_SIZE, 10,
|
(int)(imageWidth * 0.05), logoSize, 10,
|
||||||
"PingFang SC", LOGO_FONT_SIZE, LOGO_TEXT_COLOR,
|
"PingFang SC", logoFontSize, LOGO_TEXT_COLOR,
|
||||||
"NORMAL", TEXT_ALIGN_LEFT
|
"NORMAL", TEXT_ALIGN_LEFT
|
||||||
);
|
);
|
||||||
elements.add(logoTextElement);
|
elements.add(logoTextElement);
|
||||||
dynamicData.put("logoText", "帧途");
|
dynamicData.put("logoText", "帧途");
|
||||||
|
|
||||||
// 4. 计算右侧区域位置
|
// 4. 计算右侧区域位置
|
||||||
int qrcodeWidth = QRCODE_SIZE;
|
|
||||||
int qrcodeHeight = QRCODE_SIZE;
|
|
||||||
|
|
||||||
// 估算文字宽度(使用景区名和日期的较大者)
|
// 估算文字宽度(使用景区名和日期的较大者)
|
||||||
int estimatedTextWidth = Math.max(
|
int estimatedTextWidth = Math.max(
|
||||||
(request.getScenicLine() != null ? request.getScenicLine().length() : 0) * SCENIC_FONT_SIZE / 2,
|
(request.getScenicLine() != null ? request.getScenicLine().length() : 0) * scenicFontSize / 2,
|
||||||
(request.getDatetimeLine() != null ? request.getDatetimeLine().length() : 0) * DATETIME_FONT_SIZE / 2
|
(request.getDatetimeLine() != null ? request.getDatetimeLine().length() : 0) * datetimeFontSize / 2
|
||||||
);
|
);
|
||||||
|
|
||||||
int qrcodeX = canvasWidth - OFFSET_X - qrcodeWidth - QRCODE_OFFSET_X - estimatedTextWidth;
|
int qrcodeX = canvasWidth - offsetX - qrcodeSize - qrcodeOffsetX - estimatedTextWidth;
|
||||||
int qrcodeY = bottomAreaY + OFFSET_Y - QRCODE_OFFSET_Y;
|
int qrcodeY = bottomAreaY + offsetY - qrcodeOffsetY;
|
||||||
|
|
||||||
// 5. 二维码元素
|
// 5. 二维码元素
|
||||||
PuzzleElementEntity qrcodeElement = createImageElement(
|
PuzzleElementEntity qrcodeElement = createImageElement(
|
||||||
"qrcode", "二维码",
|
"qrcode", "二维码",
|
||||||
qrcodeX, qrcodeY,
|
qrcodeX, qrcodeY,
|
||||||
qrcodeWidth, qrcodeHeight, 10,
|
qrcodeSize, qrcodeSize, 10,
|
||||||
FIT_MODE_CONTAIN, null, null
|
FIT_MODE_CONTAIN, null, null
|
||||||
);
|
);
|
||||||
elements.add(qrcodeElement);
|
elements.add(qrcodeElement);
|
||||||
@@ -132,9 +154,9 @@ public class LeicaWatermarkTemplateBuilder extends AbstractWatermarkTemplateBuil
|
|||||||
|
|
||||||
// 6. 头像元素(二维码中央,可选)
|
// 6. 头像元素(二维码中央,可选)
|
||||||
if (request.getFaceUrl() != null && !request.getFaceUrl().isEmpty()) {
|
if (request.getFaceUrl() != null && !request.getFaceUrl().isEmpty()) {
|
||||||
int avatarDiameter = (int) (qrcodeHeight * 0.45);
|
int avatarDiameter = (int) (qrcodeSize * 0.45);
|
||||||
int avatarX = qrcodeX + (qrcodeWidth - avatarDiameter) / 2;
|
int avatarX = qrcodeX + (qrcodeSize - avatarDiameter) / 2;
|
||||||
int avatarY = qrcodeY + (qrcodeHeight - avatarDiameter) / 2;
|
int avatarY = qrcodeY + (qrcodeSize - avatarDiameter) / 2;
|
||||||
|
|
||||||
PuzzleElementEntity faceElement = createCircleImageElement(
|
PuzzleElementEntity faceElement = createCircleImageElement(
|
||||||
"face", "头像",
|
"face", "头像",
|
||||||
@@ -146,29 +168,29 @@ public class LeicaWatermarkTemplateBuilder extends AbstractWatermarkTemplateBuil
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 7. 计算文字位置(与二维码垂直居中)
|
// 7. 计算文字位置(与二维码垂直居中)
|
||||||
int qrcodeCenter = qrcodeY + qrcodeHeight / 2;
|
int qrcodeCenter = qrcodeY + qrcodeSize / 2;
|
||||||
int totalTextHeight = SCENIC_FONT_SIZE + DATETIME_FONT_SIZE + 10;
|
int totalTextHeight = scenicFontSize + datetimeFontSize + (int)(imageHeight * 0.01);
|
||||||
int textY = qrcodeCenter - totalTextHeight / 2;
|
int textY = qrcodeCenter - totalTextHeight / 2;
|
||||||
int textX = canvasWidth - OFFSET_X - estimatedTextWidth;
|
int textX = canvasWidth - offsetX - estimatedTextWidth;
|
||||||
|
|
||||||
// 8. 景区名文字
|
// 8. 景区名文字
|
||||||
PuzzleElementEntity scenicTextElement = createTextElement(
|
PuzzleElementEntity scenicTextElement = createTextElement(
|
||||||
"scenicLine", "景区名",
|
"scenicLine", "景区名",
|
||||||
textX, textY,
|
textX, textY,
|
||||||
estimatedTextWidth, SCENIC_FONT_SIZE + 10, 30,
|
estimatedTextWidth, scenicFontSize + (int)(imageHeight * 0.01), 30,
|
||||||
"PingFang SC", SCENIC_FONT_SIZE, SCENIC_COLOR,
|
"PingFang SC", scenicFontSize, SCENIC_COLOR,
|
||||||
"NORMAL", TEXT_ALIGN_LEFT
|
"NORMAL", TEXT_ALIGN_LEFT
|
||||||
);
|
);
|
||||||
elements.add(scenicTextElement);
|
elements.add(scenicTextElement);
|
||||||
dynamicData.put("scenicLine", request.getScenicLine() != null ? request.getScenicLine() : "");
|
dynamicData.put("scenicLine", request.getScenicLine() != null ? request.getScenicLine() : "");
|
||||||
|
|
||||||
// 9. 日期时间文字
|
// 9. 日期时间文字
|
||||||
int datetimeY = textY + SCENIC_FONT_SIZE + 5;
|
int datetimeY = textY + scenicFontSize + (int)(imageHeight * 0.005);
|
||||||
PuzzleElementEntity datetimeTextElement = createTextElement(
|
PuzzleElementEntity datetimeTextElement = createTextElement(
|
||||||
"datetimeLine", "日期时间",
|
"datetimeLine", "日期时间",
|
||||||
textX, datetimeY,
|
textX, datetimeY,
|
||||||
estimatedTextWidth, DATETIME_FONT_SIZE + 10, 30,
|
estimatedTextWidth, datetimeFontSize + (int)(imageHeight * 0.01), 30,
|
||||||
"PingFang SC", DATETIME_FONT_SIZE, DATETIME_COLOR,
|
"PingFang SC", datetimeFontSize, DATETIME_COLOR,
|
||||||
"NORMAL", TEXT_ALIGN_LEFT
|
"NORMAL", TEXT_ALIGN_LEFT
|
||||||
);
|
);
|
||||||
elements.add(datetimeTextElement);
|
elements.add(datetimeTextElement);
|
||||||
|
|||||||
@@ -170,11 +170,13 @@ public class WatermarkEdgeService {
|
|||||||
* @param info 水印信息(包含本地文件)
|
* @param info 水印信息(包含本地文件)
|
||||||
* @param type 水印类型
|
* @param type 水印类型
|
||||||
* @param adapter 存储适配器
|
* @param adapter 存储适配器
|
||||||
|
* @param recordId 记录ID(用于边缘端任务追踪,不能为空)
|
||||||
* @return 处理后的本地文件,失败返回null
|
* @return 处理后的本地文件,失败返回null
|
||||||
*/
|
*/
|
||||||
public File processWatermarkFromFile(WatermarkInfo info,
|
public File processWatermarkFromFile(WatermarkInfo info,
|
||||||
ImageWatermarkOperatorEnum type,
|
ImageWatermarkOperatorEnum type,
|
||||||
IStorageAdapter adapter) {
|
IStorageAdapter adapter,
|
||||||
|
String recordId) {
|
||||||
// 将 ImageWatermarkOperatorEnum 映射到边缘端风格
|
// 将 ImageWatermarkOperatorEnum 映射到边缘端风格
|
||||||
String style = mapTypeToStyle(type);
|
String style = mapTypeToStyle(type);
|
||||||
|
|
||||||
@@ -239,18 +241,27 @@ public class WatermarkEdgeService {
|
|||||||
.outputQuality(90)
|
.outputQuality(90)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// 6. 创建边缘任务并等待结果
|
// 6. 创建边缘任务并等待结果(使用传入的 recordId)
|
||||||
|
// recordId 转换为 Long,如果无法转换则使用哈希值
|
||||||
|
Long recordIdLong;
|
||||||
|
try {
|
||||||
|
recordIdLong = Long.parseLong(recordId);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
// 如果 recordId 不是数字(如 UUID),使用其哈希值的绝对值
|
||||||
|
recordIdLong = (long) Math.abs(recordId.hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
PuzzleEdgeRenderTaskService.TaskWaitResult result = watermarkEdgeTaskCreator.createAndWait(
|
PuzzleEdgeRenderTaskService.TaskWaitResult result = watermarkEdgeTaskCreator.createAndWait(
|
||||||
style,
|
style,
|
||||||
request,
|
request,
|
||||||
null, // recordId
|
recordIdLong, // recordId
|
||||||
null, // faceId
|
null, // faceId
|
||||||
type.getType(), // watermarkType
|
type.getType(), // watermarkType
|
||||||
DEFAULT_TIMEOUT_MS
|
DEFAULT_TIMEOUT_MS
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!result.isSuccess()) {
|
if (!result.isSuccess()) {
|
||||||
log.error("边缘端水印处理失败: error={}", result.getErrorMessage());
|
log.error("边缘端水印处理失败: recordId={}, error={}", recordId, result.getErrorMessage());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,11 +270,11 @@ public class WatermarkEdgeService {
|
|||||||
File outputFile = info.getWatermarkedFile();
|
File outputFile = info.getWatermarkedFile();
|
||||||
downloadFile(resultUrl, outputFile);
|
downloadFile(resultUrl, outputFile);
|
||||||
|
|
||||||
log.info("边缘端水印处理成功: type={}, outputFile={}", type, outputFile);
|
log.info("边缘端水印处理成功: recordId={}, type={}, outputFile={}", recordId, type, outputFile);
|
||||||
return outputFile;
|
return outputFile;
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("边缘端水印处理异常: type={}", type, e);
|
log.error("边缘端水印处理异常: recordId={}, type={}", recordId, type, e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import com.ycwl.basic.image.pipeline.stages.UpdateMemberPrintStage;
|
|||||||
import com.ycwl.basic.image.pipeline.stages.UploadStage;
|
import com.ycwl.basic.image.pipeline.stages.UploadStage;
|
||||||
import com.ycwl.basic.image.pipeline.stages.WatermarkConfig;
|
import com.ycwl.basic.image.pipeline.stages.WatermarkConfig;
|
||||||
import com.ycwl.basic.image.pipeline.stages.WatermarkStage;
|
import com.ycwl.basic.image.pipeline.stages.WatermarkStage;
|
||||||
|
import com.ycwl.basic.image.watermark.edge.WatermarkEdgeService;
|
||||||
import com.ycwl.basic.image.watermark.enums.ImageWatermarkOperatorEnum;
|
import com.ycwl.basic.image.watermark.enums.ImageWatermarkOperatorEnum;
|
||||||
import com.ycwl.basic.integration.common.manager.DeviceConfigManager;
|
import com.ycwl.basic.integration.common.manager.DeviceConfigManager;
|
||||||
import com.ycwl.basic.integration.common.manager.ScenicConfigManager;
|
import com.ycwl.basic.integration.common.manager.ScenicConfigManager;
|
||||||
@@ -159,6 +160,9 @@ public class PrinterServiceImpl implements PrinterService {
|
|||||||
);
|
);
|
||||||
@Autowired
|
@Autowired
|
||||||
private SourceRepository sourceRepository;
|
private SourceRepository sourceRepository;
|
||||||
|
@Autowired
|
||||||
|
@Lazy
|
||||||
|
private WatermarkEdgeService watermarkEdgeService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<PrinterResp> listByScenicId(Long scenicId) {
|
public List<PrinterResp> listByScenicId(Long scenicId) {
|
||||||
@@ -1052,6 +1056,9 @@ public class PrinterServiceImpl implements PrinterService {
|
|||||||
.watermarkType(watermarkType)
|
.watermarkType(watermarkType)
|
||||||
.scenicText(scenicText)
|
.scenicText(scenicText)
|
||||||
.dateFormat(dateFormat)
|
.dateFormat(dateFormat)
|
||||||
|
.edgeService(watermarkEdgeService)
|
||||||
|
.storageAdapter(StorageFactory.use())
|
||||||
|
.edgeEnabled(true)
|
||||||
.qrcodeFile(qrCodeFile)
|
.qrcodeFile(qrCodeFile)
|
||||||
.scale(scale)
|
.scale(scale)
|
||||||
.build();
|
.build();
|
||||||
|
|||||||
Reference in New Issue
Block a user