工具类
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.TextAttribute;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
/**
* Java生成水印文字(可以改造成生成图片的水印文字,生成图片的水印图片)
* Created by wesley on 2017-11-02.
*/
public class ImageUtil {
private static final Logger logger = LoggerFactory.getLogger(ImageUtil.class);
// 宽度
private static final int WIDTH = 360;
// 高度
private static final int HEIGHT = 140;
// 水印透明度
private static float alpha = 1.0f;
// 水印横向位置
private static int positionWidth = 80;
// 水印纵向位置
private static int positionHeight = 30;
// 水印文字字体
private static Font font = new Font("PingFang SC Regular", Font.PLAIN, 44);
// 水印文字颜色
private static Color color = new Color(230, 230, 230);
/**
* 创建背景白色的单水印图片
* @param os
* @param text
* @throws IOException
*/
public static void createSingleWaterMarkImage(OutputStream os, String text) throws IOException {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
String script[] = ge.getAvailableFontFamilyNames();
for(String s:script){
logger.info("字体有:{}",s);
}
// 1.创建空白图片
BufferedImage image = new BufferedImage(
WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
// 2.获取图片画笔
Graphics2D g = image.createGraphics();
// 3.设置画笔颜色
g.setColor(Color.white);
// 4.绘制矩形背景
g.fillRect(0, 0, WIDTH, HEIGHT);
// 5.绘制矩形边框
g.setColor(Color.lightGray);
g.drawRect(0, 0, WIDTH - 10, HEIGHT - 10);
// 添加水印文字
// 6、处理文字
AttributedString ats = new AttributedString(text);
ats.addAttribute(TextAttribute.FONT, font, 0, text.length());
AttributedCharacterIterator iter = ats.getIterator();
// 7、设置对线段的锯齿状边缘处理
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// 8、设置水印旋转
g.rotate(Math.toRadians(-15), (double) image.getWidth() / 2, (double) image.getHeight() / 2);
// 9、设置水印文字颜色
g.setColor(color);
// 10、设置水印文字Font
g.setFont(font);
// 11、设置水印文字透明度
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
// 12、水印位置
g.drawString(iter, positionHeight, positionWidth);
// 13、释放资源
g.dispose();
ImageIO.write(image, "JPG", os);
logger.info("打印水印成功...");
}
/**
* 创建多水印图片
* @param os
* @param text
* @throws IOException
*/
public static void createMoreWaterMarkImage(OutputStream os, String text) throws IOException {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
String script[] = ge.getAvailableFontFamilyNames();
for(String s:script){
logger.info("字体有:{}",s);
}
// 1.创建空白图片
BufferedImage image = new BufferedImage(
WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
// 2.获取图片画笔
Graphics2D g = image.createGraphics();
// 3.设置画笔颜色
g.setColor(Color.white);
// 4.绘制矩形背景
g.fillRect(0, 0, WIDTH, HEIGHT);
// 5.绘制矩形边框
g.setColor(Color.lightGray);
g.drawRect(0, 0, WIDTH - 10, HEIGHT - 10);
// 添加水印文字
// 6、设置对线段的锯齿状边缘处理
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// 7、设置水印旋转
g.rotate(Math.toRadians(-15), (double) image.getWidth() / 2, (double) image.getHeight() / 2);
// 8、设置水印文字颜色
g.setColor(color);
// 9、设置水印文字Font
g.setFont(font);
// 10、设置水印文字透明度
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
// 11、水印位置
// 计算水印位置方法一
for (int height = -WIDTH/2 ; height < 1.5*HEIGHT; height = height + 2*font.getSize()) {
for (int weight = -HEIGHT/2 ; weight < 1.5*WIDTH; weight = weight + 25*getTextLength(text)) {
g.drawString(text, weight, height);
}
}
// 计算水印位置方式二
// int x = -WIDTH/2;
// int y = -HEIGHT/2;
// while(x
// y = -HEIGHT/2;
// while(y
// //添加水印效果 第一参数->设置的内容,后面两个参数->文字在图片上的坐标位置(x,y)
// g.drawString(text, x, y);//y保证至少可以显示一个水印的高度
// y +=font.getSize()+50;//100为间隔值,即每个水印之间的间隔
// }
// x +=font.getSize()*getTextLength(text)+50;
// }
// 12、释放资源
g.dispose();
ImageIO.write(image, "JPG", os);
logger.info("打印水印成功...");
}
//获取文本长度
public static 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) {//字节长度大于1,说明是中文,那么需要延长文本长度
length++;
}
}
//计算总共有多少个字节,也就是有多少个字
length = (length % 2 == 0) ? length / 2 : length / 2 + 1;
return length;
}
/**
* 创建背景透明图片
*
* @param os
* @param text
* @throws IOException
*/
public static void createTransparentImage(OutputStream os, String text) throws IOException {
// 创建空白图片
BufferedImage image = new BufferedImage(
WIDTH, HEIGHT, BufferedImage.TYPE_INT_ARGB);
// 获取图片画笔
Graphics2D g = image.createGraphics();
// 设置背景透明度
image = g.getDeviceConfiguration().createCompatibleImage(WIDTH, HEIGHT, Transparency.TRANSLUCENT);
g.dispose();
g = image.createGraphics();
// 设置对线段的锯齿状边缘处理
// g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// 文字处理
AttributedString ats = new AttributedString(text);
ats.addAttribute(TextAttribute.FONT, font, 0, text.length());
AttributedCharacterIterator iter = ats.getIterator();
// 水印旋转
g.rotate(Math.toRadians(-15), (double) image.getWidth() / 2, (double) image.getHeight() / 2);
// 设置水印文字颜色
g.setColor(color);
// 设置水印文字Font
g.setFont(font);
// 设置水印文字透明度
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
// 设置水印文字透明度结束
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
// 水印位置
g.drawString(iter, positionHeight, positionWidth);
// 释放资源
g.dispose();
ImageIO.write(image, "PNG", os);
}
}
controller中使用:
/**
* 生成文字水印图片
*
* @param response
* @param staffNo
*/
@RequestMapping("/getImage/")
public void getImage(HttpServletResponse response) {
response.setContentType("image/*");
try {
OutputStream os = response.getOutputStream();
String text = “测试水印文字图片”;
logger.info("需要打印的水印文字:{}",text);
ImageUtil.createTransparentImage(os, text);
} catch (IOException e) {
logger.error("打印水印异常...");
}
}
效果图: