批量给图片添加水印

宋正兵 on 2020-09-28

Java 如何给图片添加水印

需要源码点这里

想要在 java 程序中绘图,一定绕不开 Graphics 类,这里用它的子类 Graphics2D 类,java 绘图的基本操作流程如下:

  • 使用 ImageIO 类的 read() 方法将需要被添加水印的图片加载;
  • 创建一个 BufferedImage 实例 ,在其构造函数里指定长,宽,高,类型为 BufferedImage.TYPE_INT_RGB ,即创建一个指定分辨率的空图片 bimage
  • 调用 BufferedImage 对象的 createGraphics() 方法,得到 Graphics2D 实例;
  • 使用 Graphics2D 实例进行绘图,所以绘图操作的坐标基于创建此 Graphics2D 实例的 BufferedImage 实例。示例中在图片上画了一串字符串;
  • 调用 Graphics2D 对象的 dispose() 方法,进行绘图处理,使绘图效果应用到 BufferedImage 对象;
  • 使用 ImageIO 类的 write() 方法将 BufferedImage 对象转换到文件或二进制流。
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
// 加载图片
Image image = ImageIO.read(new File("images/test.png"));
int width = 200, height = 250;
// 创建图片对象
BufferedImage bimage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 基于图片对象打开绘图
Graphics2D graphics = image.createGraphics();

// 绘图逻辑 START (基于业务逻辑进行绘图处理)……
// 绘制一串字符串
Font font = new Font("宋体",Font.BOLD, 10);
g.setFont(font);
g.setColor(Color.RED);
// 绘制当前可用的指定图像。在该图形上下文的坐标空间中,图像的左上角位于(x,y)。
g.drawImage(image, 0, 0, null);
g.drawString("水印测试", 0, font.getSize());
// 绘图逻辑 END

// 处理绘图,输出
graphics.dispose();
// 将绘制好的图片写入到图片
// ImageIO.write(image, "png", new File("abc.png"));
// 得到图片的格式后缀
String formatName = file.getName().split("\\.")[1];
ImageIO.write(bimage, formatName, new File("abc.png"));

批量给图片添加水印

如果想要批量的给图片添加水印,想到的办法是将待处理图片都存放到同一目录下,这里指定为 images/ ,通过调用 File 对象的 listFiles() 方法获得目录下所有文件的相对路径(注意它包括目录下的子目录,所以需要判断当前操作对象是不是文件),再对每个 File 对象进行绘图处理。

1
2
3
4
5
6
7
// 加载目录路径
String path = "images/";
File[] files = new File(path).listFiles();
for (File file : files) {
if (!file.isDirectory()) {
// 添加水印操作
}

利用配置文件添加水印

java 读取配置文件的方法有好几种,这里选择的是通过读取 .preperties 文件来进行配置。

观察上面的代码,我们能抽取出来部分配置信息并写入 watermark.properties 文件中,让 java 程序自动读取,而使用者只需要进行这部分信息的配置,并且把待添加水印的图片存放到指定路径即可。 watermark.properties 文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 待添加水印图片的路径
basePath=images/
# 文字水印的内容
context=测试水印
# 文字水印的字体
fontName=宋体
# 文字水印字体的样式
# PLAIN 1 BOLD 2 ITALIC 3
fontStyle=1
# 文字水印字体的大小
fontsize=20
# 文字水印字体的颜色
color=white
# 文字水印字体的位置,上中下,每层左中右三个点位
# 1~9
location=8

创建输入缓冲流 InputStream 类, filePath 是配置文件 watermark.properties 的相对路径。然后利用 properties 类来读取配置文件中的属性,利用方法 getProperty(String key) 可以得到文件内的属性配置。

这里我并没有理解通过输入缓冲流进行读取配置文件为啥这么写,如果有知道的同学欢迎发邮件指教

1
2
3
4
5
6
7
8
9
// 通过输入缓冲流进行读取配置文件
InputStream InputStream = new BufferedInputStream(new FileInputStream(new File(filePath)));
// 加载配置
Properties p = new Properties();
try {
p.load(bf);
} catch (IOException e1) {
e1.printStackTrace();
}