Java为图片加水印工具类
一、简介
- 使用Java在图片上加上水印,可以添加文字、图片
- 编写一个工具类的代码优化和整理
- 使用建造者模式提高工具类的可配置性
二、效果图
三、基本参数
// +++++++++++++++ 配置参数 +++++++++++++++++++
/** 文字水印内容 */
private String fontText = null;
/** 图片水印内容 */
private String imgText = null;
/** 操作的图片文件 */
private String filePath = null;
// +++++++++++++ 初始化一些参数 +++++++++++++++++
/** 图片宽度 */
private int width;
/** 图片高度 */
private int height;
/** 画笔操作 */
private Graphics2D graphics2D = null;
/** 图片缓冲区 */
private BufferedImage bufferedImage = null;
// +++++++++++++ 自定义的水印参数 ++++++++++++++
/** 文字字体 */
private String fontName = null;
/** 文字样式 */
private int fontStyle;
/** 文字大小 */
private int fontSize;
/** 文字颜色 */
private Color fontColor;
/** 透明度 */
private float alpha;
/** 外框宽度 */
private int borderWidth;
/** 旋转高度 */
private double angdeg;
/** 间距 */
private int spacing;
/** 最后图片保存路径 */
private String savePath = null;
四、工具方法
水印位置
public static enum Position{
/** 上左 */
TOP_LEFT(1),
/** 上右 */
TOP_RIGHT(2),
/** 下左 */
BOTTOM_LEFT(3),
/** 下右 */
BOTTOM_RIGHT(4)
;
public int type;
Position(int type) {
this.type = type;
}
public int getType() {
return type;
}
}
设置文字或者图片水印位置
/**
* @function 设置文字或者图片水印位置
* @param position 添加水印的位置
* @param waterWidth 添加水印的宽度
* @param waterHeight 添加水印的高度
* @param type true:文字,false:图片
* @return int[] x, y
*/
private int[] setPosition (int position, int waterWidth, int waterHeight, boolean type) {
int x = width - waterWidth;
int y = height - waterHeight;
switch (position) {
case 1:
x = type ? borderWidth : 0;
y = type ? borderWidth : 0;
break;
case 2:
y = type ? borderWidth : 0;
break;
case 3:
x = type ? borderWidth : 0;
y = type ? y - borderWidth : y;
break;
case 4:
default:
x = type ? x - borderWidth : x;
y = type ? y - borderWidth : y;
break;
}
return new int[]{x, y};
}
初始化参数
初始化BufferImage
、Graphisc2D
和目标图片的宽和高。
/**
* 初始化参数
*/
private void init () {
try {
// 获取图片示例,并获取图片的高度,宽度
Image img = ImageIO.read(new File(filePath));
width = img.getWidth(null);
height = img.getHeight(null);
// 创建图片缓冲区
bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 创建绘图工具
graphics2D = bufferedImage.createGraphics();
// 将原图放到缓冲区
graphics2D.drawImage(img, 0, 0, width, height, null);
} catch (IOException e) {
System.out.println("文件读写异常");
e.printStackTrace();
}
}
将操作之后的图片存在磁盘
如何没有填写保存路径,将会将原图片覆盖。
/**
* 将图片保存到磁盘
*/
private void save () {
String path = null;
if ((savePath == null) || (savePath.equals(""))) {
path = filePath;
} else {
path = savePath;
}
// 将缓冲区图片放到磁盘上
try (FileOutputStream os = new FileOutputStream(path)) {
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os);
encoder.encode((bufferedImage));
} catch (IOException e) {
System.out.println("文件读写异常");
e.printStackTrace();
}
}
设置文字水印的宽和高
对于中英文字符宽度不一样,所以要对中英文进行不同的处理。
/**
* 获取文字位置
* @param text
* @return
*/
private int getTextLength (String text) {
int len = text.length();
for (int i = 0; i < text.length(); i++) {
String s = String.valueOf(text.charAt(i));
if (s.getBytes().length > 1) {
len ++;
}
}
return len % 2 == 0 ? len / 2 : len / 2 + 1;
}
添加单个文字水印
/**
* 添加单个文字水印
* @throws IOException
* @param place
*/
public void addFontWater(Position place) {
init();
// 创建文字水印的样式
graphics2D.setFont(new Font(fontName, fontStyle, fontSize));
// 文字颜色
graphics2D.setColor(fontColor);
// 获取文字位置x,y坐标
int type = place.getType();
int[] position = setPosition(type, fontSize * getTextLength(fontText), fontSize, true);
int x = position[0];
int y = position[1] + fontSize;
// 将文字写入指定位置,并关闭画笔资源
graphics2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
graphics2D.drawString(fontText, x, y);
graphics2D.dispose();
save();
}
创建那个操作句柄
public static Builder create = new ImageWaterTool.Builder();
建造者模式设置属性
因为部分属性是默认,但是有些默认的属性是可以使用者自定义的,所以使用建造者进行对象属性构建是最好的。
public class ImageWaterTool {
// ++++++++ 配置参数 ++++++++++++++++
/** 文字水印内容 */
private String fontText = null;
/** 图片水印内容 */
private String imgText = null;
/** 操作的图片文件 */
private String filePath = null;
// .....
public ImageWaterTool(Builder builder) {
this.fontText = builder.fontText;
this.imgText = builder.imgText;
this.filePath = builder.filePath;
// ....
}
public static class Builder {
// +++++++++++ 配置参数 +++++++++++++++
/** 文字水印内容 */
private String fontText = null;
/** 图片水印内容 */
private String imgText = null;
/** 操作的图片文件 */
private String filePath = null;
// .....
public Builder setFontText(String fontText) {
this.fontText = fontText;
return this;
}
public Builder setImgText(String imgText) {
this.imgText = imgText;
return this;
}
public Builder setFilePath(String filePath) {
this.filePath = filePath;
return this;
}
// ....
}
public static enum Position{
// ....
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/**
* @function 设置文字或者图片水印位置
* @param position 添加水印的位置
* @param waterWidth 添加水印的宽度
* @param waterHeight 添加水印的高度
* @param type true:文字 —— false:图片
* @return int[] x, y
*/
private int[] setPosition (int position, int waterWidth, int waterHeight, boolean type) {
// ....
}
/**
* 初始化参数
*/
private void init () {
// ....
}
/**
* 将图片保存到磁盘
*/
private void save () {
// ....
}
/**
* 获取文字位置
* @param text
* @return
*/
private int getTextLength (String text) {
// ....
}
/**
* 添加单个文字水印
* @throws IOException
* @param place
*/
public void addFontWater(Position place) {
// ....
}
/**
* 添加单个图片水印
* @throws IOException
*/
public void addPicWater (Position place) throws IOException {
// ....
}
/**
* 添加多个文字水印
* @throws IOException
*/
public void addManyFontWater () {
// ....
}
/**
* 添加多个图片水印
* @throws IOException
*/
public void addManyPicWater () throws IOException {
// ....
}
public static Builder create = new ImageWaterTool.Builder();
public static void main(String[] args) throws Exception {
ImageWaterTool.create
.setFilePath("C:\\Users\\long\\Desktop\\test-1.png")
.setFontText("https://blog.c.net/yhflyl")
.setFontSize(30)
.build()
.addFontWater(Position.BOTTOM_RIGHT);
}
}
使用
public static void main(String[] args) throws Exception {
ImageWaterTool.create
// 本地文件路径
.setFilePath("C:\\Users\\long\\Desktop\\test-1.png")
// 添加的文字水印
.setFontText("https://blog.c.net/yhflyl")
// 文字大小
.setFontSize(30)
.build()
.addFontWater(Position.BOTTOM_RIGHT);
}
五、完整代码
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author 墨龙吟
* @version 1.0.0
* @ClassName ImageWaterUtil.java
* @Email [email protected]
* @Description TODO 文件添加水印
* @createTime 2019年09月09日 - 23:32
*/
public class ImageWaterTool {
// ++++++++++++++++++++++++++ 配置参数 +++++++++++++++++++++++++++++++++++++++++++++++++++
/** 文字水印内容 */
private String fontText = null;
/** 图片水印内容 */
private String imgText = null;
/** 操作的图片文件 */
private String filePath = null;
// ++++++++++++++++++++++++++ 初始化一些参数 ++++++++++++++++++++++++++++++++++++++++++++++
/** 图片宽度 */
private int width;
/** 图片高度 */
private int height;
/** 画笔操作 */
private Graphics2D graphics2D = null;
/** 图片缓冲区 */
private BufferedImage bufferedImage = null;
// +++++++++++++++++++++++++++++ 自定义的水印参数 ++++++++++++++++++++++++++++++++++++++++
/** 文字字体 */
private String fontName = null;
/** 文字样式 */
private int fontStyle;
/** 文字大小 */
private int fontSize;
/** 文字颜色 */
private Color fontColor;
/** 透明度 */
private float alpha;
/** 外框宽度 */
private int borderWidth;
/** 旋转高度 */
private double angdeg;
/** 间距 */
private int spacing;
/** 最后图片保存路径 */
private String savePath = null;
public ImageWaterTool(Builder builder) {
this.fontText = builder.fontText;
this.imgText = builder.imgText;
this.filePath = builder.filePath;
this.fontName = builder.fontName;
this.fontStyle = builder.fontStyle;
this.fontSize = builder.fontSize;
this.fontColor = builder.fontColor;
this.alpha = builder.alpha;
this.borderWidth = builder.borderWidth;
this.angdeg = builder.angdeg;
this.spacing = builder.spacing;
this.savePath = builder.savePath;
}
public static class Builder {
// ++++++++++++++++++++++++++ 配置参数 +++++++++++++++++++++++++++++++++++++++++++++++++++
/** 文字水印内容 */
private String fontText = null;
/** 图片水印内容 */
private String imgText = null;
/** 操作的图片文件 */
private String filePath = null;
// +++++++++++++++++++++++++++++ 自定义的水印参数 ++++++++++++++++++++++++++++++++++++++++
/** 文字字体 */
private String fontName = "微软雅黑";
/** 文字样式 */
private int fontStyle = Font.BOLD | Font.ITALIC;
/** 文字大小 */
private int fontSize = 30;
/** 文字颜色 */
private Color fontColor = Color.black;
/** 透明度 */
private float alpha = 0.3f;
/** 外框宽度 */
private int borderWidth = 20;
/** 旋转高度 */
private double angdeg = 30;
/** 间距 */
private int spacing = 200;
/** 最后图片保存路径 */
private String savePath = null;
public Builder setFontText(String fontText) {
this.fontText = fontText;
return this;
}
public Builder setImgText(String imgText) {
this.imgText = imgText;
return this;
}
public Builder setFilePath(String filePath) {
this.filePath = filePath;
return this;
}
public Builder setFontName(String fontName) {
this.fontName = fontName;
return this;
}
public Builder setFontStyle(int fontStyle) {
this.fontStyle = fontStyle;
return this;
}
public Builder setFontSize(int fontSize) {
this.fontSize = fontSize;
return this;
}
public Builder setFontColor(Color fontColor) {
this.fontColor = fontColor;
return this;
}
public Builder setAlpha(float alpha) {
this.alpha = alpha;
return this;
}
public Builder setBorderWidth(int borderWidth) {
this.borderWidth = borderWidth;
return this;
}
public Builder setAngdeg(double angdeg) {
this.angdeg = angdeg;
return this;
}
public Builder setSpacing(int spacing) {
this.spacing = spacing;
return this;
}
public Builder setSavePath(String savePath) {
this.savePath = savePath;
return this;
}
public ImageWaterTool build () throws Exception {
return new ImageWaterTool(this);
}
}
public static enum Position{
/** 上左 */
TOP_LEFT(1),
/** 上右 */
TOP_RIGHT(2),
/** 下左 */
BOTTOM_LEFT(3),
/** 下右 */
BOTTOM_RIGHT(4)
;
public int type;
Position(int type) {
this.type = type;
}
public int getType() {
return type;
}
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/**
* @function 设置文字或者图片水印位置
* @param position 添加水印的位置
* @param waterWidth 添加水印的宽度
* @param waterHeight 添加水印的高度
* @param type true:文字 —— false:图片
* @return int[] x, y
*/
private int[] setPosition (int position, int waterWidth, int waterHeight, boolean type) {
int x = width - waterWidth;
int y = height - waterHeight;
switch (position) {
case 1:
x = type ? borderWidth : 0;
y = type ? borderWidth : 0;
break;
case 2:
y = type ? borderWidth : 0;
break;
case 3:
x = type ? borderWidth : 0;
y = type ? y - borderWidth : y;
break;
case 4:
default:
x = type ? x - borderWidth : x;
y = type ? y - borderWidth : y;
break;
}
return new int[]{x, y};
}
/**
* 初始化参数
*/
private void init () {
try {
// 获取图片示例,并获取图片的高度,宽度
Image img = ImageIO.read(new File(filePath));
width = img.getWidth(null);
height = img.getHeight(null);
// 创建图片缓冲区
bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 创建绘图工具
graphics2D = bufferedImage.createGraphics();
// 将原图放到缓冲区
graphics2D.drawImage(img, 0, 0, width, height, null);
} catch (IOException e) {
System.out.println("文件读写异常");
e.printStackTrace();
}
}
/**
* 将图片保存到磁盘
*/
private void save () {
String path = null;
if ((savePath == null) || (savePath.equals(""))) {
path = filePath;
} else {
path = savePath;
}
// 将缓冲区图片放到磁盘上
try (FileOutputStream os = new FileOutputStream(path)) {
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os);
encoder.encode((bufferedImage));
} catch (IOException e) {
System.out.println("文件读写异常");
e.printStackTrace();
}
}
/**
* 获取文字位置
* @param text
* @return
*/
private int getTextLength (String text) {
int len = text.length();
for (int i = 0; i < text.length(); i++) {
String s = String.valueOf(text.charAt(i));
if (s.getBytes().length > 1) {
len ++;
}
}
return len % 2 == 0 ? len / 2 : len / 2 + 1;
}
/**
* 添加单个文字水印
* @throws IOException
* @param place
*/
public void addFontWater(Position place) {
init();
// 创建文字水印的样式
graphics2D.setFont(new Font(fontName, fontStyle, fontSize));
// 文字颜色
graphics2D.setColor(fontColor);
// 获取文字位置x,y坐标
int type = place.getType();
int[] position = setPosition(type, fontSize * getTextLength(fontText), fontSize, true);
int x = position[0];
int y = position[1] + fontSize;
// 将文字写入指定位置,并关闭画笔资源
graphics2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
graphics2D.drawString(fontText, x, y);
graphics2D.dispose();
save();
}
/**
* 添加单个图片水印
* @throws IOException
*/
public void addPicWater (Position place) throws IOException {
init();
// 创建图片水印
Image imageWater = ImageIO.read(new File(imgText));
// 获取文字位置x,y坐标
int type = place.getType();
int[] position = setPosition(type, imageWater.getWidth(null), imageWater.getHeight(null), false);
int x = position[0];
int y = position[1];
// 将文字写入指定位置,并关闭画笔资源
graphics2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
graphics2D.drawImage(imageWater, x, y, null);
graphics2D.dispose();
save();
}
/**
* 添加多个文字水印
* @throws IOException
*/
public void addManyFontWater () {
init();
// 创建文字水印的样式
graphics2D.setFont(new Font(fontName, fontStyle, fontSize));
graphics2D.setColor(fontColor);
// 获取文字宽高
int waterWidth = fontSize * getTextLength(fontText);
int waterHeight = fontSize;
// 将文字写入指定位置,并关闭画笔资源
graphics2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
// 将文字旋转30度
graphics2D.rotate(Math.toRadians(angdeg), width / 2, height / 2);
// 添加多个
int x = -width / 2;
while (x < width * 1.5) {
int y = -height / 2;
while (y < height * 1.5) {
graphics2D.drawString(fontText, x, y);
y += waterHeight + spacing;
}
x += waterWidth + spacing;
}
graphics2D.dispose();
save();
}
/**
* 添加多个图片水印
* @throws IOException
*/
public void addManyPicWater () throws IOException {
// 初始化
init();
// 创建图片水印
Image imageWater = ImageIO.read(new File(imgText));
// 获取水印图片的宽高
int waterWidth = imageWater.getWidth(null);
int waterHeight = imageWater.getHeight(null);
// 将文字写入指定位置,并关闭画笔资源
graphics2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
// 将文字旋转30度
graphics2D.rotate(Math.toRadians(angdeg), width / 2, height / 2);
// 添加多个
int x = -width / 2;
while (x < width * 1.5) {
int y = -height / 2;
while (y < height * 1.5) {
graphics2D.drawImage(imageWater, x, y, null);
y += waterHeight + spacing;
}
x += waterWidth + spacing;
}
graphics2D.dispose();
save();
}
public static Builder create = new ImageWaterTool.Builder();
public static void main(String[] args) throws Exception {
ImageWaterTool.create
.setFilePath("C:\\Users\\long\\Desktop\\test-1.png")
.setFontText("https://blog.c.net/yhflyl")
.setFontSize(30)
.build()
.addFontWater(Position.BOTTOM_RIGHT);
// 多个文字水印
// ImageWaterTool.create
// // 设置水印文字
// .setFontText("我的小笨蛋")
// .setFilePath("C:\\Users\\long\\Desktop\\笨蛋1.jpg")
// // 设置添加水印后的图片路径
.setSavePath("C:\\Users\\long\\Desktop\\pic-444.png")
// // 设置多个文字之间的距离
// .setSpacing(100)
// .setAngdeg(150)
// //设置水印的透明度
// .setAlpha(0.2f)
// .build()
// .addManyFontWater();
// 多个图片水印
// ImageWaterTool.create
// .setFilePath("C:\\Users\\long\\Desktop\\笨蛋.jpg")
// .setImgText("C:\\Users\\long\\Desktop\\logo.png")
// .build()
// .addManyPicWater();
}
}
五、关注一波,感谢