|
@@ -0,0 +1,496 @@
|
|
|
|
+package com.gqy.common.utils.image;
|
|
|
|
+
|
|
|
|
+import javax.imageio.ImageIO;
|
|
|
|
+import java.awt.*;
|
|
|
|
+import java.awt.geom.AffineTransform;
|
|
|
|
+import java.awt.image.BufferedImage;
|
|
|
|
+import java.io.File;
|
|
|
|
+import java.io.IOException;
|
|
|
|
+import java.util.Base64;
|
|
|
|
+
|
|
|
|
+import java.io.ByteArrayOutputStream;
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 图片水印工具类
|
|
|
|
+ */
|
|
|
|
+public class WatermarkUtils {
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 默认参数值
|
|
|
|
+ */
|
|
|
|
+ private static final int DEFAULT_MARGIN = 20;
|
|
|
|
+ private static final int DEFAULT_SPACING = 5;
|
|
|
|
+ private static final float DEFAULT_ALPHA = 0.3f;
|
|
|
|
+ private static final int DEFAULT_FONT_SIZE = 30;
|
|
|
|
+ private static final int DEFAULT_POSITION = 4; // 右下角
|
|
|
|
+ private static final int DEFAULT_DEGREE = -30; // 默认旋转角度
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 添加文字水印并返回Base64
|
|
|
|
+ *
|
|
|
|
+ * @param srcImage 源图片
|
|
|
|
+ * @param text 水印文字
|
|
|
|
+ * @param font 字体
|
|
|
|
+ * @param color 水印颜色
|
|
|
|
+ * @param alpha 透明度(0.0 ~ 1.0f)
|
|
|
|
+ * @param position 水印位置 (1:左上 2:右上 3:左下 4:右下 5:居中)
|
|
|
|
+ * @param degree 旋转角度
|
|
|
|
+ * @return Base64字符串
|
|
|
|
+ */
|
|
|
|
+ public static String addTextWatermark(BufferedImage srcImage, String text, Font font, Color color, float alpha, int position, Integer degree) {
|
|
|
|
+ try {
|
|
|
|
+ // 使用默认的 margin, spacing 和 repeat 值调用完整版本
|
|
|
|
+ BufferedImage watermarkedImage = addTextWatermarkToImage(
|
|
|
|
+ srcImage, text, font, color, alpha, position, degree
|
|
|
|
+ );
|
|
|
|
+ return convertToBase64(watermarkedImage);
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 添加文字水印并返回Base64(完整参数版本)
|
|
|
|
+ */
|
|
|
|
+ public static String addTextWatermark(
|
|
|
|
+ BufferedImage srcImage,
|
|
|
|
+ String text,
|
|
|
|
+ Font font,
|
|
|
|
+ Color color,
|
|
|
|
+ float alpha,
|
|
|
|
+ int position,
|
|
|
|
+ Integer degree,
|
|
|
|
+ int margin,
|
|
|
|
+ int spacing,
|
|
|
|
+ boolean repeat) {
|
|
|
|
+ try {
|
|
|
|
+ BufferedImage watermarkedImage = addTextWatermarkToImage(
|
|
|
|
+ srcImage, text, font, color, alpha, position, degree,
|
|
|
|
+ margin, spacing, repeat
|
|
|
|
+ );
|
|
|
|
+ return convertToBase64(watermarkedImage);
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 添加图片水印并返回Base64
|
|
|
|
+ *
|
|
|
|
+ * @param srcImage 源图片
|
|
|
|
+ * @param watermarkImage 水印图片
|
|
|
|
+ * @param position 水印位置 (1:左上 2:右上 3:左下 4:右下 5:居中)
|
|
|
|
+ * @param alpha 透明度(0.0 ~ 1.0f)
|
|
|
|
+ * @return Base64字符串
|
|
|
|
+ */
|
|
|
|
+ public static String addImageWatermark(BufferedImage srcImage, BufferedImage watermarkImage, int position, float alpha) {
|
|
|
|
+ try {
|
|
|
|
+ BufferedImage watermarkedImage = addImageWatermarkToImage(srcImage, watermarkImage, position, alpha);
|
|
|
|
+ return convertToBase64(watermarkedImage);
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 将BufferedImage转换为Base64字符串
|
|
|
|
+ */
|
|
|
|
+ private static String convertToBase64(BufferedImage image) throws IOException {
|
|
|
|
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
|
|
+ ImageIO.write(image, "png", baos);
|
|
|
|
+ byte[] bytes = baos.toByteArray();
|
|
|
|
+ baos.close();
|
|
|
|
+ return "data:image/png;base64," + Base64.getEncoder().encodeToString(bytes);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 绘制文本块
|
|
|
|
+ */
|
|
|
|
+ private static void drawTextBlock(Graphics2D g2d, String[] lines, int x, int y,
|
|
|
|
+ int lineHeight, Integer degree, FontMetrics fontMetrics) {
|
|
|
|
+ // 保存当前变换状态
|
|
|
|
+ AffineTransform originalTransform = g2d.getTransform();
|
|
|
|
+
|
|
|
|
+ // 计算文本块的整体宽度和高度
|
|
|
|
+ int blockWidth = 0;
|
|
|
|
+ int blockHeight = lineHeight * lines.length;
|
|
|
|
+ for (String line : lines) {
|
|
|
|
+ blockWidth = Math.max(blockWidth, fontMetrics.stringWidth(line));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 计算旋转中心点
|
|
|
|
+ int centerX = x + blockWidth / 2;
|
|
|
|
+ int centerY = y + blockHeight / 2;
|
|
|
|
+
|
|
|
|
+ if (degree != null) {
|
|
|
|
+ // 先平移到旋转中心
|
|
|
|
+ g2d.translate(centerX, centerY);
|
|
|
|
+ // 执行旋转
|
|
|
|
+ g2d.rotate(Math.toRadians(degree));
|
|
|
|
+ // 平移回原点,考虑文本块的尺寸
|
|
|
|
+ g2d.translate(-blockWidth / 2, -blockHeight / 2);
|
|
|
|
+
|
|
|
|
+ // 绘制文本
|
|
|
|
+ int currentY = fontMetrics.getAscent();
|
|
|
|
+ for (String line : lines) {
|
|
|
|
+ int lineWidth = fontMetrics.stringWidth(line);
|
|
|
|
+ // 居中对齐每一行
|
|
|
|
+ int lineX = (blockWidth - lineWidth) / 2;
|
|
|
|
+ g2d.drawString(line, lineX, currentY);
|
|
|
|
+ currentY += lineHeight;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ // 不旋转时直接绘制
|
|
|
|
+ int currentY = y;
|
|
|
|
+ for (String line : lines) {
|
|
|
|
+ g2d.drawString(line, x, currentY);
|
|
|
|
+ currentY += lineHeight;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 恢复变换状态
|
|
|
|
+ g2d.setTransform(originalTransform);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 添加文字水印到图片
|
|
|
|
+ */
|
|
|
|
+ private static BufferedImage addTextWatermarkToImage(
|
|
|
|
+ BufferedImage srcImage, String text, Font font, Color color,
|
|
|
|
+ float alpha, int position, Integer degree) {
|
|
|
|
+ // 使用默认值调用完整版本
|
|
|
|
+ return addTextWatermarkToImage(
|
|
|
|
+ srcImage, text, font, color, alpha, position, degree,
|
|
|
|
+ DEFAULT_MARGIN, DEFAULT_SPACING, true);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 添加文字水印到图片(完整参数版本)
|
|
|
|
+ */
|
|
|
|
+ private static BufferedImage addTextWatermarkToImage(
|
|
|
|
+ BufferedImage srcImage, String text, Font font, Color color,
|
|
|
|
+ float alpha, int position, Integer degree,
|
|
|
|
+ int margin, int spacing, boolean repeat) {
|
|
|
|
+ int width = srcImage.getWidth();
|
|
|
|
+ int height = srcImage.getHeight();
|
|
|
|
+
|
|
|
|
+ BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
|
|
|
+ Graphics2D g2d = bufferedImage.createGraphics();
|
|
|
|
+
|
|
|
|
+ // 设置渲染质量
|
|
|
|
+ g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
|
|
|
+ g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
|
|
|
+ g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
|
|
|
|
+
|
|
|
|
+ // 绘制原图
|
|
|
|
+ g2d.drawImage(srcImage, 0, 0, width, height, null);
|
|
|
|
+
|
|
|
|
+ // 设置水印文字透明度
|
|
|
|
+ g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
|
|
|
|
+
|
|
|
|
+ // 设置水印文字颜色和字体
|
|
|
|
+ g2d.setColor(color);
|
|
|
|
+ g2d.setFont(font);
|
|
|
|
+
|
|
|
|
+ // 处理多行文字
|
|
|
|
+ String[] lines = text.split("\n");
|
|
|
|
+ FontMetrics fontMetrics = g2d.getFontMetrics(font);
|
|
|
|
+ int lineHeight = fontMetrics.getHeight() + spacing;
|
|
|
|
+
|
|
|
|
+ // 计算文本整体尺寸
|
|
|
|
+ int totalTextHeight = lineHeight * lines.length - spacing;
|
|
|
|
+ int maxTextWidth = 0;
|
|
|
|
+ for (String line : lines) {
|
|
|
|
+ maxTextWidth = Math.max(maxTextWidth, fontMetrics.stringWidth(line));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 如果有旋转,调整文本块尺寸
|
|
|
|
+ double rotationRad = degree != null ? Math.toRadians(degree) : 0;
|
|
|
|
+ int rotatedWidth = (int) Math.abs(maxTextWidth * Math.cos(rotationRad) +
|
|
|
|
+ totalTextHeight * Math.sin(rotationRad));
|
|
|
|
+ int rotatedHeight = (int) Math.abs(maxTextWidth * Math.sin(rotationRad) +
|
|
|
|
+ totalTextHeight * Math.cos(rotationRad));
|
|
|
|
+
|
|
|
|
+ // 计算初始位置,考虑旋转后的尺寸
|
|
|
|
+ int startX = 0;
|
|
|
|
+ int startY = 0;
|
|
|
|
+ switch (position) {
|
|
|
|
+ case 1: // 左上
|
|
|
|
+ startX = margin + rotatedWidth/2;
|
|
|
|
+ startY = margin + rotatedHeight/2;
|
|
|
|
+ break;
|
|
|
|
+ case 2: // 右上
|
|
|
|
+ startX = width - rotatedWidth/2 - margin;
|
|
|
|
+ startY = margin + rotatedHeight/2;
|
|
|
|
+ break;
|
|
|
|
+ case 3: // 左下
|
|
|
|
+ startX = margin + rotatedWidth/2;
|
|
|
|
+ startY = height - rotatedHeight/2 - margin;
|
|
|
|
+ break;
|
|
|
|
+ case 4: // 右下
|
|
|
|
+ startX = width - rotatedWidth/2 - margin;
|
|
|
|
+ startY = height - rotatedHeight/2 - margin;
|
|
|
|
+ break;
|
|
|
|
+ case 5: // 居中
|
|
|
|
+ startX = width / 2;
|
|
|
|
+ startY = height / 2;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ startX = margin + rotatedWidth/2;
|
|
|
|
+ startY = height - rotatedHeight/2 - margin;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (repeat) {
|
|
|
|
+ // 计算平铺间距,考虑旋转后的尺寸和边距
|
|
|
|
+ int xStep = (int)(rotatedWidth * 1.5); // 增加水平间距
|
|
|
|
+ int yStep = (int)(rotatedHeight * 1.5); // 增加垂直间距
|
|
|
|
+
|
|
|
|
+ // 计算起始偏移,确保覆盖边缘
|
|
|
|
+ int startOffsetX = -xStep;
|
|
|
|
+ int startOffsetY = -yStep;
|
|
|
|
+
|
|
|
|
+ // 计算结束位置,确保覆盖整个图片
|
|
|
|
+ int endX = width + xStep;
|
|
|
|
+ int endY = height + yStep;
|
|
|
|
+
|
|
|
|
+ // 根据旋转角度调整起始位置,确保完整覆盖
|
|
|
|
+ if (degree != null) {
|
|
|
|
+ // 扩展覆盖范围
|
|
|
|
+ startOffsetX -= rotatedWidth;
|
|
|
|
+ startOffsetY -= rotatedHeight;
|
|
|
|
+ endX += rotatedWidth;
|
|
|
|
+ endY += rotatedHeight;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 绘制水印网格
|
|
|
|
+ for (int y = startOffsetY; y < endY; y += yStep) {
|
|
|
|
+ for (int x = startOffsetX; x < endX; x += xStep) {
|
|
|
|
+ // 交错排列,使水印分布更均匀
|
|
|
|
+ int offsetX = (y / yStep % 2 == 0) ? 0 : xStep / 2;
|
|
|
|
+ drawTextBlock(g2d, lines, x + offsetX, y, lineHeight, degree, fontMetrics);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ // 单个水印
|
|
|
|
+ drawTextBlock(g2d, lines, startX - maxTextWidth/2, startY - totalTextHeight/2,
|
|
|
|
+ lineHeight, degree, fontMetrics);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ g2d.dispose();
|
|
|
|
+ return bufferedImage;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 添加图片水印到图片
|
|
|
|
+ */
|
|
|
|
+ private static BufferedImage addImageWatermarkToImage(BufferedImage srcImage, BufferedImage watermarkImage, int position, float alpha) {
|
|
|
|
+ int width = srcImage.getWidth();
|
|
|
|
+ int height = srcImage.getHeight();
|
|
|
|
+ int watermarkWidth = watermarkImage.getWidth();
|
|
|
|
+ int watermarkHeight = watermarkImage.getHeight();
|
|
|
|
+
|
|
|
|
+ BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
|
|
|
+ Graphics2D g2d = bufferedImage.createGraphics();
|
|
|
|
+
|
|
|
|
+ // 设置渲染质量
|
|
|
|
+ g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
|
|
|
+ g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
|
|
|
|
+ g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
|
|
|
+
|
|
|
|
+ // 绘制原图
|
|
|
|
+ g2d.drawImage(srcImage, 0, 0, width, height, null);
|
|
|
|
+
|
|
|
|
+ // 设置水印图片透明度
|
|
|
|
+ g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
|
|
|
|
+
|
|
|
|
+ // 计算水印位置
|
|
|
|
+ int x = 0;
|
|
|
|
+ int y = 0;
|
|
|
|
+ switch (position) {
|
|
|
|
+ case 1: // 左上
|
|
|
|
+ x = 10;
|
|
|
|
+ y = 10;
|
|
|
|
+ break;
|
|
|
|
+ case 2: // 右上
|
|
|
|
+ x = width - watermarkWidth - 10;
|
|
|
|
+ y = 10;
|
|
|
|
+ break;
|
|
|
|
+ case 3: // 左下
|
|
|
|
+ x = 10;
|
|
|
|
+ y = height - watermarkHeight - 10;
|
|
|
|
+ break;
|
|
|
|
+ case 4: // 右下
|
|
|
|
+ x = width - watermarkWidth - 10;
|
|
|
|
+ y = height - watermarkHeight - 10;
|
|
|
|
+ break;
|
|
|
|
+ case 5: // 居中
|
|
|
|
+ x = (width - watermarkWidth) / 2;
|
|
|
|
+ y = (height - watermarkHeight) / 2;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ x = 10;
|
|
|
|
+ y = height - watermarkHeight - 10;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 绘制水印图片
|
|
|
|
+ g2d.drawImage(watermarkImage, x, y, watermarkWidth, watermarkHeight, null);
|
|
|
|
+ g2d.dispose();
|
|
|
|
+
|
|
|
|
+ return bufferedImage;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 添加文字水印并同时保存文件和返回Base64
|
|
|
|
+ *
|
|
|
|
+ * @param srcImage 源图片
|
|
|
|
+ * @param text 水印文字
|
|
|
|
+ * @param font 字体
|
|
|
|
+ * @param color 水印颜色
|
|
|
|
+ * @param alpha 透明度(0.0 ~ 1.0f)
|
|
|
|
+ * @param position 水印位置 (1:左上 2:右上 3:左下 4:右下 5:居中)
|
|
|
|
+ * @param degree 旋转角度
|
|
|
|
+ * @param outputPath 输出文件路径
|
|
|
|
+ * @return WatermarkResult 包含处理结果的对象
|
|
|
|
+ */
|
|
|
|
+ public static WatermarkResult addTextWatermarkAndSave(BufferedImage srcImage, String text, Font font,
|
|
|
|
+ Color color, float alpha, int position, Integer degree, String outputPath) {
|
|
|
|
+ WatermarkResult result = new WatermarkResult();
|
|
|
|
+ try {
|
|
|
|
+ // 添加水印
|
|
|
|
+ BufferedImage watermarkedImage = addTextWatermarkToImage(srcImage, text, font, color, alpha, position, degree);
|
|
|
|
+
|
|
|
|
+ // 保存文件并转换Base64
|
|
|
|
+ saveImageAndToBase64(watermarkedImage, outputPath, result);
|
|
|
|
+
|
|
|
|
+ return result;
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ result.setSuccess(false);
|
|
|
|
+ result.setErrorMessage("添加水印失败:" + e.getMessage());
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 添加图片水印并同时保存文件和返回Base64
|
|
|
|
+ */
|
|
|
|
+ public static WatermarkResult addImageWatermarkAndSave(BufferedImage srcImage, BufferedImage watermarkImage,
|
|
|
|
+ int position, float alpha, String outputPath) {
|
|
|
|
+ WatermarkResult result = new WatermarkResult();
|
|
|
|
+ try {
|
|
|
|
+ // 添加水印
|
|
|
|
+ BufferedImage watermarkedImage = addImageWatermarkToImage(srcImage, watermarkImage, position, alpha);
|
|
|
|
+
|
|
|
|
+ // 保存文件并转换Base64
|
|
|
|
+ saveImageAndToBase64(watermarkedImage, outputPath, result);
|
|
|
|
+
|
|
|
|
+ return result;
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ result.setSuccess(false);
|
|
|
|
+ result.setErrorMessage("添加水印失败:" + e.getMessage());
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 保存图片并转换为Base64
|
|
|
|
+ */
|
|
|
|
+ private static void saveImageAndToBase64(BufferedImage image, String outputPath, WatermarkResult result) throws IOException {
|
|
|
|
+ // 确保输出目录存在
|
|
|
|
+ File outputFile = new File(outputPath);
|
|
|
|
+ outputFile.getParentFile().mkdirs();
|
|
|
|
+
|
|
|
|
+ // 保存图片
|
|
|
|
+ ImageIO.write(image, "png", outputFile);
|
|
|
|
+ result.setSavedPath(outputPath);
|
|
|
|
+
|
|
|
|
+ // 转换为Base64
|
|
|
|
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
|
|
+ ImageIO.write(image, "png", baos);
|
|
|
|
+ String base64 = "data:image/png;base64," + Base64.getEncoder().encodeToString(baos.toByteArray());
|
|
|
|
+ result.setBase64(base64);
|
|
|
|
+ baos.close();
|
|
|
|
+
|
|
|
|
+ result.setSuccess(true);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 处理结果类
|
|
|
|
+ */
|
|
|
|
+ public static class WatermarkResult {
|
|
|
|
+ private String base64;
|
|
|
|
+ private String savedPath;
|
|
|
|
+ private boolean success;
|
|
|
|
+ private String errorMessage;
|
|
|
|
+
|
|
|
|
+ public WatermarkResult() {
|
|
|
|
+ this.success = true;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Getters and Setters
|
|
|
|
+ public String getBase64() { return base64; }
|
|
|
|
+ public void setBase64(String base64) { this.base64 = base64; }
|
|
|
|
+ public String getSavedPath() { return savedPath; }
|
|
|
|
+ public void setSavedPath(String savedPath) { this.savedPath = savedPath; }
|
|
|
|
+ public boolean isSuccess() { return success; }
|
|
|
|
+ public void setSuccess(boolean success) { this.success = success; }
|
|
|
|
+ public String getErrorMessage() { return errorMessage; }
|
|
|
|
+ public void setErrorMessage(String errorMessage) {
|
|
|
|
+ this.errorMessage = errorMessage;
|
|
|
|
+ this.success = false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 使用示例
|
|
|
|
+ */
|
|
|
|
+ public static void main(String[] args) {
|
|
|
|
+ try {
|
|
|
|
+ // 读取原图
|
|
|
|
+ BufferedImage sourceImage = ImageIO.read(new File("source.jpg"));
|
|
|
|
+
|
|
|
|
+ // 添加文字水印
|
|
|
|
+ Font font = new Font("微软雅黑", Font.BOLD, 30);
|
|
|
|
+ WatermarkResult textResult = addTextWatermarkAndSave(
|
|
|
|
+ sourceImage,
|
|
|
|
+ "测试水印",
|
|
|
|
+ font,
|
|
|
|
+ Color.WHITE,
|
|
|
|
+ 0.5f,
|
|
|
|
+ 4,
|
|
|
|
+ 45,
|
|
|
|
+ "D:/watermark/output/text_watermark.png"
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ if (textResult.isSuccess()) {
|
|
|
|
+ System.out.println("文字水印已保存到: " + textResult.getSavedPath());
|
|
|
|
+ System.out.println("文字水印Base64: " + textResult.getBase64());
|
|
|
|
+ } else {
|
|
|
|
+ System.out.println("文字水印添加失败: " + textResult.getErrorMessage());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 添加图片水印
|
|
|
|
+ BufferedImage watermarkImage = ImageIO.read(new File("watermark.png"));
|
|
|
|
+ WatermarkResult imageResult = addImageWatermarkAndSave(
|
|
|
|
+ sourceImage,
|
|
|
|
+ watermarkImage,
|
|
|
|
+ 4,
|
|
|
|
+ 0.5f,
|
|
|
|
+ "D:/watermark/output/image_watermark.png"
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ if (imageResult.isSuccess()) {
|
|
|
|
+ System.out.println("图片水印已保存到: " + imageResult.getSavedPath());
|
|
|
|
+ System.out.println("图片水印Base64: " + imageResult.getBase64());
|
|
|
|
+ } else {
|
|
|
|
+ System.out.println("图片水印添加失败: " + imageResult.getErrorMessage());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+}
|