文字根据自生偏移量定位,确保居中展示

This commit is contained in:
2025-07-22 00:18:56 +08:00
parent 22dea22fc1
commit 1eb527574b
3 changed files with 35 additions and 6 deletions

View File

@@ -107,13 +107,30 @@ public class LeicaWatermarkOperator implements IOperator {
int dtLineHeight = datetimeFontMetrics.getHeight(); int dtLineHeight = datetimeFontMetrics.getHeight();
int scenicLineWidth = scenicFontMetrics.stringWidth(info.getScenicLine()); int scenicLineWidth = scenicFontMetrics.stringWidth(info.getScenicLine());
int datetimeLineWidth = scenicFontMetrics.stringWidth(info.getDatetimeLine()); int datetimeLineWidth = scenicFontMetrics.stringWidth(info.getDatetimeLine());
g2d.drawImage(qrcodeImage, newImage.getWidth() + EXTRA_BORDER_PX - OFFSET_X - newQrcodeWidth - QRCODE_OFFSET_X - Math.max(scenicLineWidth, datetimeLineWidth), EXTRA_BORDER_PX + baseImage.getHeight() + OFFSET_Y - QRCODE_OFFSET_Y, newQrcodeWidth, newQrcodeHeight, null); // 计算二维码的位置
int qrcodeX = newImage.getWidth() + EXTRA_BORDER_PX - OFFSET_X - newQrcodeWidth - QRCODE_OFFSET_X - Math.max(scenicLineWidth, datetimeLineWidth);
int qrcodeY = EXTRA_BORDER_PX + baseImage.getHeight() + OFFSET_Y - QRCODE_OFFSET_Y;
g2d.drawImage(qrcodeImage, qrcodeX, qrcodeY, newQrcodeWidth, newQrcodeHeight, null);
// 计算文字与二维码垂直居中对齐的Y坐标
int qrcodeTop = qrcodeY;
int qrcodeBottom = qrcodeTop + newQrcodeHeight;
int qrcodeCenter = (qrcodeTop + qrcodeBottom) / 2;
// 两行文字的总高度
int totalTextHeight = scenicLineHeight + dtLineHeight;
// 计算第一行文字的Y坐标(基线位置),使两行文字整体垂直居中于二维码
int textStartY = qrcodeCenter - totalTextHeight / 2 + scenicFontMetrics.getAscent();
g2d.setFont(scenicFont); g2d.setFont(scenicFont);
g2d.setColor(scenicColor); g2d.setColor(scenicColor);
g2d.drawString(info.getScenicLine(), newImage.getWidth() + EXTRA_BORDER_PX - OFFSET_X - Math.max(scenicLineWidth, datetimeLineWidth), EXTRA_BORDER_PX + baseImage.getHeight() + OFFSET_Y + scenicLineHeight + scenicLineHeight * FONT_GLOBAL_OFFSET_PERCENT); g2d.drawString(info.getScenicLine(), newImage.getWidth() + EXTRA_BORDER_PX - OFFSET_X - Math.max(scenicLineWidth, datetimeLineWidth), textStartY);
g2d.setFont(datetimeFont); g2d.setFont(datetimeFont);
g2d.setColor(datetimeColor); g2d.setColor(datetimeColor);
g2d.drawString(info.getDatetimeLine(), newImage.getWidth() + EXTRA_BORDER_PX - OFFSET_X - Math.max(scenicLineWidth, datetimeLineWidth), EXTRA_BORDER_PX + baseImage.getHeight() + OFFSET_Y + scenicLineHeight + dtLineHeight + dtLineHeight * FONT_GLOBAL_OFFSET_PERCENT); g2d.drawString(info.getDatetimeLine(), newImage.getWidth() + EXTRA_BORDER_PX - OFFSET_X - Math.max(scenicLineWidth, datetimeLineWidth), textStartY + scenicLineHeight);
String fileName = info.getWatermarkedFile().getName(); String fileName = info.getWatermarkedFile().getName();
String formatName = "jpg"; // 默认格式为 jpg String formatName = "jpg"; // 默认格式为 jpg
if (fileName.endsWith(".png")) { if (fileName.endsWith(".png")) {

View File

@@ -89,12 +89,24 @@ public class NormalWatermarkOperator implements IOperator {
g2d.setClip(circle); g2d.setClip(circle);
g2d.drawImage(qrcodeImage, offsetX, offsetY + QRCODE_OFFSET_Y, newQrcodeWidth, newQrcodeHeight, null); g2d.drawImage(qrcodeImage, offsetX, offsetY + QRCODE_OFFSET_Y, newQrcodeWidth, newQrcodeHeight, null);
g2d.setClip(originalClip); g2d.setClip(originalClip);
// 计算文字与二维码垂直居中对齐的Y坐标
int qrcodeTop = offsetY + QRCODE_OFFSET_Y;
int qrcodeBottom = qrcodeTop + newQrcodeHeight;
int qrcodeCenter = (qrcodeTop + qrcodeBottom) / 2;
// 两行文字的总高度
int totalTextHeight = scenicLineHeight + dtLineHeight;
// 计算第一行文字的Y坐标(基线位置),使两行文字整体垂直居中于二维码
int textStartY = qrcodeCenter - totalTextHeight / 2 + scenicFontMetrics.getAscent();
g2d.setFont(scenicFont); g2d.setFont(scenicFont);
g2d.setColor(scenicColor); g2d.setColor(scenicColor);
g2d.drawString(info.getScenicLine(), offsetX + newQrcodeWidth + QRCODE_OFFSET_X, offsetY + scenicLineHeight + FONT_GLOBAL_OFFSET_PERCENT * scenicLineHeight); g2d.drawString(info.getScenicLine(), offsetX + newQrcodeWidth + QRCODE_OFFSET_X, textStartY);
g2d.setFont(datetimeFont); g2d.setFont(datetimeFont);
g2d.setColor(datetimeColor); g2d.setColor(datetimeColor);
g2d.drawString(info.getDatetimeLine(), offsetX + newQrcodeWidth + QRCODE_OFFSET_X, offsetY + scenicLineHeight + dtLineHeight + FONT_GLOBAL_OFFSET_PERCENT * dtLineHeight); g2d.drawString(info.getDatetimeLine(), offsetX + newQrcodeWidth + QRCODE_OFFSET_X, textStartY + scenicLineHeight);
String fileName = info.getWatermarkedFile().getName(); String fileName = info.getWatermarkedFile().getName();
String formatName = "jpg"; // 默认格式为 jpg String formatName = "jpg"; // 默认格式为 jpg
if (fileName.endsWith(".png")) { if (fileName.endsWith(".png")) {

View File

@@ -16,7 +16,7 @@ public class WatermarkOperatorTest {
@Test @Test
public void testProcess() throws Exception { public void testProcess() throws Exception {
WatermarkInfo info = new WatermarkInfo(); WatermarkInfo info = new WatermarkInfo();
info.setOriginalFile(new File("e2d32de7-6e85-4e07-b42f-477347073539.jpg")); info.setOriginalFile(new File("38e1285c-84d0-464a-810d-053e9502e257.jpg"));
info.setQrcodeFile(new File("cxzh_t.jpg")); info.setQrcodeFile(new File("cxzh_t.jpg"));
info.setScenicLine("川西竹海一日游!"); info.setScenicLine("川西竹海一日游!");
info.setDatetimeLine("2XXX年XX月XX日 留念"); info.setDatetimeLine("2XXX年XX月XX日 留念");