0%

图片添加水印

背景(废话)

最近项目中出现客户要求使用手机端拍照实现水印的功能,起初以为业务比较简单,但具体实现起来发现了很多问题,水印打印的时候根据图片的横向宽度确定水印的打印位置和水印文字的大小

使用方法

水印打印的工具类

添加水印的工具类代码如下,里面都有注释就,就不再赘述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Date;

/**
* @Title: ImageUtils
* @Package: com.jxl.workbench.common
* @Description: 图片处理工具类
* @author: Daniel
* @date: 2020-12-02 11:23
* @version: V1.0
**/
public class ImageUtils {
/**
* 添加水印
* @param
* @return
* @exception
* @author Daniel
* @date 2020/11/11 14:47
**/
public static BufferedImage addWaterMark(Image docFileImg, String location){

int docFileImgHeight = docFileImg.getHeight(null);
int docFileImgWidth = docFileImg.getWidth(null);

//加水印
BufferedImage bufImg = new BufferedImage(docFileImgWidth,docFileImgHeight,BufferedImage.TYPE_INT_RGB);

//获取 Graphics2D 对象
Graphics2D g = bufImg.createGraphics();
//设置绘图区域
g.drawImage(docFileImg, 0, 0, docFileImgWidth, docFileImgHeight, null);
//设置字体
int timeFontSize = (docFileImgHeight>docFileImgWidth?docFileImgWidth:docFileImgHeight)/8;
Font timeFont = new Font("微软雅黑", Font.PLAIN, timeFontSize);
// 根据图片的背景设置水印颜色
g.setColor(Color.white);
g.setFont(timeFont);
//设置抗锯齿
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

String currentTime = DateUtils.dateTimeNow(DateUtils.HH_MM);
//设置下部的时间
//获取时间文字长度
int timLen = g.getFontMetrics(g.getFont()).charsWidth(currentTime.toCharArray(),0,currentTime.length());
int timeX = (docFileImgWidth - timLen)/2;
int timeY = docFileImgHeight*5/6;
g.drawString(currentTime, timeX, timeY);

//设置时间下面的日期、星期和地址
String dateAddrStr = DateUtils.dateTimeNow(DateUtil.DATE_FORMAT_YYYY_MM_DD)+" " +DateUtils.dateToWeek(new Date())+" "+location;

int dateAddrFontSize = (docFileImgHeight>docFileImgWidth?docFileImgWidth:docFileImgHeight)/25;
Font dateAddrFont = new Font("微软雅黑", Font.PLAIN, dateAddrFontSize);
g.setFont(dateAddrFont);
int dateAddrLen = g.getFontMetrics(g.getFont()).charsWidth(dateAddrStr.toCharArray(),0,dateAddrStr.length());
int dateAddrX = (docFileImgWidth - dateAddrLen)/2;
int dateAddrY = docFileImgHeight*9/10;
g.drawString(dateAddrStr, dateAddrX, dateAddrY);

g.dispose();
return bufImg;
}
}

调用方法

该调用方法里面包含了如何将MultipartFile转化为ImageIO数据

1
2
3
4
5
6
7
8
9
10
11
12
Image docFileImg = ImageIO.read(file.getInputStream());

//添加水印
BufferedImage bufImg = ImageUtils.addWaterMark(docFileImg,location);

//下面的filePath是文件的存储目录,fileId是文件的文件名或自己生成的随机数,extName是文件的格式,当然如果为了安全可以不加文件类型,自己解析的时候注意即可
String fileSrc = filePath + fileId +extName;

//创建文件输出流
FileOutputStream outImgStream = new FileOutputStream(fileSrc);
//输出文件到本地
ImageIO.write(bufImg, "png", outImgStream);