import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import java.io.OutputStream;
public class ImageWatermarkUtil {
/**
* 水印之间的横向间隔
*/
private static final int X_MOVE = 200;
/**
* 水印之间的纵向间隔
*/
private static final int Y_MOVE = 200;
/**
* 给图片添加文字水印
*
* @param markerText 水印文字内容
* @param inputStream 图片输入流
* @param outputStream 图片输出流
*/
public static void markerText(String markerText, InputStream inputStream, OutputStream outputStream) {
int fontSize = 36;
Color color = Color.GRAY;
float alpha = 0.5f;
try {
Font font = new Font("SansSerif", Font.BOLD, fontSize);
// 获取文字水印的大小
int maxLen = getStringLength(font, markerText);
int maxHigh = fontSize + 10; // 单行文字高度
BufferedImage srcImg = ImageIO.read(inputStream);//文件转化为图片
int srcImgWidth = srcImg.getWidth(null);//获取图片的宽
int srcImgHeight = srcImg.getHeight(null);//获取图片的高
// 加水印
Graphics2D g = srcImg.createGraphics();//得到画笔
g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
g.setColor(color); //设置水印颜色
g.setFont(font);//设置字体
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));//设置水印文字透明度
g.rotate(Math.toRadians(-45), (double) srcImgWidth / 2, (double) srcImgHeight / 2);//设置水印旋转
// 旋转45度后需要更大的覆盖范围
//一个div 每行每列的打印到图片 上
int rowsNumber = srcImgHeight / maxLen + srcImgHeight % maxLen;// 图片的高 除以 文字水印的宽 打印的行数(以文字水印的宽为间隔)
int columnsNumber = srcImgWidth / maxLen + srcImgWidth % maxLen;//图片的宽 除以 文字水印的宽 每行打印的列数(以文字水印的宽为间隔)
//至少打印一次
if (rowsNumber < 1) {
rowsNumber = 1;
}
if (columnsNumber < 1) {
columnsNumber = 1;
}
int yz = 0;
//遍历每行打印到图片上的个数
for (int a = 0; a < columnsNumber; a++) {
int t = 0;
int y = 40 + 10 + t;
// 文字叠加位置
int tempX = -(int) (srcImgWidth * 0.7);
int tempY = -(int) (srcImgHeight * 0.7) + y + yz;
// 单字符长度
int tempCharLen = 0;
// 单行字符总长度临时计算
int tempLineLen = 0;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < markerText.length(); i++) {
char tempChar = markerText.charAt(i);
tempCharLen = g.getFontMetrics(g.getFont()).charWidth(tempChar);
tempLineLen += tempCharLen;
// 和图片的长度进行对应的比较操作
if (tempLineLen >= srcImgWidth) {
// 长度已经满一行,进行文字叠加
g.drawString(sb.toString(), tempX, tempY);
t = t + 40;
// 清空内容,重新追加
sb.delete(0, sb.length());
tempY += 40;
tempLineLen = 0;
}
// 追加字符
sb.append(tempChar);
}
// 遍历每列打印到图片上的个数
for (int z = 0; z < rowsNumber; z++) {
// 最后叠加余下的文字
g.drawString(sb.toString(), tempX, tempY);
tempX = tempX + maxLen + X_MOVE;
}
yz = yz + maxHigh + Y_MOVE;
}
g.dispose();// 释放资源
ImageIO.write(srcImg, "JPEG", outputStream);// 输出流
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取文字水印的宽
*
* @param font
* @param markContent
* @return
*/
public static int getStringLength(Font font, String markContent) {
if (markContent == null || markContent.isEmpty()) {
return 0;
}
if (null == font) {
font = new Font(null);
}
JLabel label = new JLabel(markContent);
FontMetrics metrics = label.getFontMetrics(font);
//文字水印的宽
return metrics.stringWidth(label.getText());
}
}