public static void createMarkForPic2(String sourcePath, String outputPath,
String watermarkText, Color textColor,
float opacity, String fontName,
int fontSize, int spacing,
Color borderColor, String fileExtension,
Map<String, Object> params) {
// 强制设置为20pt字体
fontSize = 20;
try {
// 读取原始图片
BufferedImage sourceImage = ImageIO.read(new File(sourcePath));
int width = sourceImage.getWidth();
int height = sourceImage.getHeight();
// 创建画布
BufferedImage watermarkedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = watermarkedImage.createGraphics();
g2d.drawImage(sourceImage, 0, 0, null);
// 智能自适应方案
int baseSize = Math.min(width, height);
int adaptiveFontSize = (int)(baseSize * 0.03); // 根据图片尺寸动态计算
fontSize = Math.max(20, adaptiveFontSize); // 至少20pt
// 设置字体(加粗)
Font font = new Font(fontName, Font.BOLD, fontSize);
g2d.setFont(font);
// 计算水印位置(智能居中偏左上)
FontMetrics metrics = g2d.getFontMetrics();
int textWidth = metrics.stringWidth(watermarkText);
int textHeight = metrics.getHeight();
int posX = width / 20; // 水平位置:1/20宽度处
int posY = textHeight + (height / 20); // 垂直位置:文字高度+1/20高度处
// 自适应透明度(深色背景用高透明度,浅色背景用低透明度)
float adaptiveOpacity = calculateAdaptiveOpacity(sourceImage, posX, posY, textWidth, textHeight);
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, adaptiveOpacity));
// 绘制水印(白字黑边)
g2d.setColor(Color.BLACK);
g2d.drawString(watermarkText, posX-1, posY-1);
g2d.drawString(watermarkText, posX+1, posY-1);
g2d.drawString(watermarkText, posX-1, posY+1);
g2d.drawString(watermarkText, posX+1, posY+1);
g2d.setColor(Color.WHITE);
g2d.drawString(watermarkText, posX, posY);
g2d.dispose();
// 保存图片
String formatName = fileExtension.startsWith(".") ?
fileExtension.substring(1) : fileExtension;
ImageIO.write(watermarkedImage, formatName, new File(outputPath));
} catch (Exception e) {
e.printStackTrace();
}
}
// 智能计算背景区域平均亮度(用于确定最佳透明度)
private static float calculateAdaptiveOpacity(BufferedImage image, int x, int y, int width, int height) {
// 采样水印区域背景色
int sampleCount = 0;
long totalBrightness = 0;
int endX = Math.min(x + width, image.getWidth());
int endY = Math.min(y + height, image.getHeight());
for (int i = x; i < endX; i += 5) { // 每隔5像素采样
for (int j = y; j < endY; j += 5) {
int rgb = image.getRGB(i, j);
int r = (rgb >> 16) & 0xFF;
int g = (rgb >> 8) & 0xFF;
int b = rgb & 0xFF;
totalBrightness += (r + g + b) / 3;
sampleCount++;
}
}
if (sampleCount == 0) return 0.7f;
float avgBrightness = totalBrightness / (float)sampleCount;
// 亮度越高(背景越亮),透明度越低(水印越明显)
return avgBrightness > 150 ? 0.8f :
avgBrightness > 100 ? 0.7f : 0.6f;
}这段添加水印的代码需要修改为如果已存在水印就先清除水印再重新添加水印,避免重复添加水印导致水印重叠看不清,可以接受每次添加水印时如果识别到有水印存在,将水印区域设置成白色,再重新添加水印的方案,或者有其他更好的方案也行