写在最前面
上周零零碎碎花了一周的时间研究水印的开发,现在终于写了个入门级的Demo,做下笔记同时分享出来供大家参考。
Demo是在我上次写的 JAVA实用案例之文件导入导出(POI方式) 框架基础上搭建的,基于Spring+SpringMVC。如果有错误还请大家指正。
简单介绍
水印开发是web开发中一种比较常见的功能,实现的代码很简单,具体的实现步骤我也会以代码为基础详细讲述。其实以我个人的理解,我把水印的类型和开发流程分为以下几种。
水印的类型:
单文字水印
单图片水印
多文字水印
多图片水印
水印的开发流程:
创建图片缓存对象
创建Java绘图工具对象
使用绘图工具工具对象将原图绘制到缓存图片对象
使用绘图工具对象将水印(文字/图片)绘制到缓存图片
创建图像编码工具类
使用图像编码工具类,输出缓存图像到目标文件
效果图:
上传页:
原图:
单文字水印:
单图片水印:
多文字水印:
多图片水印:
单文字水印开发
所谓单文字水印,就是在一张图片上添加一条文字水印。其中我们主要的流程是通过ImageIO工具类解码对应的图片,然后创建BufferImage对象,通过BufferImage对象创建Graphics2D对象,再通过Graphics2D对象绘制原图到BufferImage对象。然后,我们还可以使用Graphics2D对象来设置水印的相关信息,如水印内容、字体大小、字体风格等。
这里需要说明的是我们需要计算水印文本的宽度,中文长度即文本宽度,英文长度为文本宽度的二分之一。具体可以参考我源码中的相关内容。
//计算水印文本长度
//1、中文长度即文本长度 2、英文长度为文本长度二分之一
public int getTextLength(String text){
//水印文字长度
int length = text.length();
for (int i = 0; i < text.length(); i++) {
String s =String.valueOf(text.charAt(i));
if (s.getBytes().length>1) {
length++;
}
}
length = length%2==0?length/2:length/2+1;
return length;
}
//添加单条文字水印方法
public String textWaterMark(MultipartFile myFile,String imageFileName) {
InputStream is =null;
OutputStream os =null;
int X = 636;
int Y = 700;
try {
//使用ImageIO解码图片
Image image = ImageIO.read(myFile.getInputStream());
//计算原始图片宽度长度
int width = image.getWidth(null);
int height = image.getHeight(null);
//创建图片缓存对象
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//创建java绘图工具对象
Graphics2D graphics2d = bufferedImage.createGraphics();
//参数主要是,原图,坐标,宽高
graphics2d.drawImage(image, 0, 0, width, height, null);
graphics2d.setFont(new Font(FONT_NAME, FONT_STYLE, FONT_SIZE));
graphics2d.setColor(FONT_COLOR);
//使用绘图工具将水印绘制到图片上
//计算文字水印宽高值
int waterWidth = FONT_SIZE*getTextLength(MARK_TEXT);
int waterHeight = FONT_SIZE;
//计算水印与原图高宽差
int widthDiff = width-waterWidth;
int heightDiff = height-waterHeight;
//水印坐标设置
if (X > widthDiff) {
X = widthDiff;
}
if (Y > heightDiff) {
Y &