水印会随着水印文本的长度而自动是修改字体大小,使其可以合理的放置于一行。
效果图如下:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import javax.imageio.ImageIO;
import javax.swing.JLabel;
import java.awt.FontMetrics;
import java.awt.Color;
import java.awt.AlphaComposite;
import java.awt.Font;
import java.awt.RenderingHints;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfGState;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.redxun.common.exception.asserts.BizAssertTips;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class WaterMarkUtil {
//为了使文字向左移动5像素
private static int interval = -5;
/**
* PDF加文字水印
* @param inputFile PDF文件输入路径
* @param outputFile PDF文件输出路径
* @param waterMarkName 自定义水印
* @throws Exception
*/
public static void waterMarkPdf(InputStream inputFile,OutputStream outputFile, String waterMarkName) throws Exception {
//根据水印文字长度,更改水印文字大小
int size = 0;
if (waterMarkName.length() <= 13) {
size = 30;
}else if(waterMarkName.length() > 13 && waterMarkName.length() <= 33) {
size = 25;
} else {
//通过文字长度自动调节字体大小
size = 800/waterMarkName.length()-1;
}
PdfStamper stamper = null;
PdfReader reader = null;
try {
reader = new PdfReader(inputFile);
stamper = new PdfStamper(reader, outputFile);
//设置文字样式
BaseFont base = BaseFont.createFont("STSong-Light","UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
Rectangle pageRect = null;
PdfGState gs = new PdfGState();
//设置透明度
gs.setFillOpacity(0.2f);
gs.setStrokeOpacity(0.4f);
int total = reader.getNumberOfPages() + 1;
JLabel label = new JLabel();
FontMetrics metrics;
int textH = 0;
int textW = 0;
//设置自定义水印
label.setText(waterMarkName);
metrics = label.getFontMetrics(label.getFont());
textH = metrics.getHeight();
textW = metrics.stringWidth(label.getText());
PdfContentByte under = null;
for (int i = 1; i < total; i++) {
pageRect = reader.getPageSizeWithRotation(i);
under = stamper.getOverContent(i);
under.saveState();
under.setGState(gs);
under.beginText();
under.setFontAndSize(base, size);
//调整for循环的宽高可更改水印位置,高:textH 宽:textW
for (int height = interval + textH; height < pageRect.getHeight(); height = height + textH*10) {
for (int width = interval + textW; width < pageRect.getWidth() + textW; width = width + textW*5) {
//水印文字成21度角倾斜
//这里居中 故设置x为中线。
under.showTextAligned(Element.ALIGN_CENTER, waterMarkName, pageRect.getWidth()/2 , height - textH, 21);
}
}
// 添加水印文字
under.endText();
}
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
//关闭流
if(stamper != null) {
stamper.close();
}
if(reader != null) {
reader.close();
}
}
}
public static void main(String[] args) throws Exception {
FileInputStream in = new FileInputStream("C:\\Users\\hxd\\Desktop\\xxx_20230111151716.jpg");
FileOutputStream out = new FileOutputStream("C:\\Users\\hxd\\Desktop\\xxx_20230111151716-1.jpg");
clearImage(in, out, "这是一个测试水印这是一个测试水印这是一个");
}
/**
* 图片构建水印的时候高度间隔
*/
static final int hight_interval=220;
/**
* 图片加文字水印
* @param text 水印内容
* @param transparency 清晰度
* @param imageName 图片名(含后缀)
* @param path 图片保存位置
*/
public static void clearImage(InputStream inputFile,OutputStream outputFile, String waterMarkName) {
try {
// 读取本地图片文件
// 将文件对象转化为图片对象(限png、jpg、gif)
BufferedImage image = ImageIO.read(inputFile);
//设置水印字体大小
int size = 5;
if (image.getWidth() >= waterMarkName.length() * 30) {
size = 30;
}else if (image.getWidth() >= waterMarkName.length() * 20) {
size = 20;
}else if (image.getWidth() >= waterMarkName.length() * 10) {
size = 10;
} else {
size = image.getWidth()/waterMarkName.length()+1;
}
Graphics2D pen = image.createGraphics();
pen.setColor(Color.BLACK);
// 设置画笔字体样式为微软雅黑 斜体:Font.ITALIC
pen.setFont(new Font("微软雅黑", Font.BOLD, size));
//文字倾斜
//double shx, double shy
//0表示x轴的旋转 y表示y轴旋转,我们不希望x轴有旋转。故设置为0.如果需要y的倾斜度陡峭或者平缓,改第二个参数shy
pen.shear(0, -0.32);
//消除文字锯齿
pen.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
//设置文字透明度
pen.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.3F));
//获取文本长度,用来设置坐标
int len = waterMarkName.length();
//获取水印坐标位置
int width = image.getWidth()/2;
if (image.getWidth() - (len*size) > 0) {
//根据水印字体长度,控制水印位置
width = image.getWidth()/2 - (len/2)*size;
} else {
width=1;
}
int imgH = image.getHeight();
if(imgH /2 < hight_interval) {
//添加水印 从最中间开始加水印
pen.drawString(waterMarkName, width, imgH/2);
} else {
for (int h = 10; h < imgH; h+=hight_interval) {
pen.drawString(waterMarkName, width, h);
}
}
//此处需设置图片类型
ImageIO.write(image, "png", outputFile);
outputFile.close();
} catch (Exception e) {
e.printStackTrace();
BizAssertTips.fail("生成图片水印失败");
}
}
}