整体思路如下 :
(删除了部分代码,不影响代码执行,根据实际情况进行调整)
- 获取需要打水印的图片
- 获取画布对象
- 设置水印属性
- 为图片画上水印数据
- 生成带水印的图片
- 返回路径
import cn.hutool.core.util.StrUtil;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ResourceUtils;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.util.Date;
public static String watermark(Date date, String address, String filePath) {
logger.info("图片水印");
// 旋转角度 可以自定义旋转度数
Integer degree = 0;
OutputStream os = null;
// 文件路径
String courseFile = getNewFilePath();
StringBuilder watermarkImagePath = new StringBuilder();
// 需要根据原图获取图片类型 默认jpg
String imgType = "jpg";
if (filePath.length() == 0) {
return null;
}
String fileName = filePath.substring(filePath.lastIndexOf("/") + 1);
watermarkImagePath.append(courseFile).append("\\").append("watermark_").append(fileName);
// 图片类型
if (StrUtil.isNotBlank(fileName)) {
String[] split = fileName.split("\\.");
if (split.length > 1) {
imgType = split[1];
}
}
try {
// ImageIO.read(new URL(filePath)); 读取 远程比如阿里云腾讯云的图片 需要用new URL 方法读取
BufferedImage srcImage = ImageIO.read(new URL(filePath));
// 读取本地图片用下面 此处要区分,否则会空指针
// BufferedImage srcImage = ImageIO.read(filePath);
BufferedImage bufImage = new BufferedImage(srcImage.getWidth(null), srcImage.getHeight(null), BufferedImage.TYPE_INT_RGB);
// 得到画布对象
Graphics2D graphics2D = bufImage.createGraphics();
// 设置对线段的锯齿状边缘处理
graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
graphics2D.drawImage(srcImage.getScaledInstance(srcImage.getWidth(null), srcImage.getHeight(null), Image.SCALE_SMOOTH),
0, 0, null);
if (null != degree) {
// 设置水印旋转角度及坐标
graphics2D.rotate(Math.toRadians(degree), (double) bufImage.getWidth() / 3, (double) bufImage.getHeight() / 3);
}
// 透明度
float alpha = 0.8f;
// 字体样式
String fontStyle = "SimSun";
graphics2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
// 字体大小 Font.PLAIN 正常字体 Font.BOLD 加粗字体
int fontSize = srcImage.getWidth()/500*20;
// 设置颜色和画笔粗细
graphics2D.setColor(Color.white);
graphics2D.setStroke(new BasicStroke(20));
graphics2D.setFont(new Font(fontStyle, Font.PLAIN, fontSize));
// 水印位置 根据自定义 注意 X Y 轴的定点是图片的左上角
// X Y 轴的距离加上字体的大小会导致偏移不在正中心位置 需要根据情况加上或减去字体大小 不进行操作可能会导致字体重叠
int x = (srcImage.getWidth(null)) / 2 - fontSize;
int y = (int) ((srcImage.getHeight(null)) * 0.8);
// 下方的代码控制水印的字体大小位置等
StringBuilder dateStr= new StringBuilder();
if (date != null) {
// 时间 重新设定字体 需要增大 加粗
graphics2D.setStroke(new BasicStroke(20));
graphics2D.setFont(new Font(fontStyle, Font.BOLD, fontSize+20));
String time = DateUtil.getDate(date, "HH:mm");
graphics2D.drawString(time,x-fontSize-20,y);
}
if (StrUtil.isNotBlank(address)) {
// 加上字体的高度 否则字体会重叠 使用者根据情况加减
y +=fontSize+20;
graphics2D.drawString(address,x,y);
}
graphics2D.dispose();
os = new FileOutputStream(watermarkImagePath.toString());
// 生成图片 (可设置 jpg或者png格式)
ImageIO.write(bufImage, imgType, os);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (os != null) {
os.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 返回图片路径
return watermarkImagePath.toString();
}
// 获取当前项目文件路径
private static String getNewFilePath() {
String classPath = null;
try {
classPath = ResourceUtils.getURL("classpath:").getPath();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
File newFile = new File(classPath, "static/image/");
if (!newFile.exists()) {
newFile.mkdirs();
}
return newFile.getAbsolutePath();
}