效果图如下
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import com.spire.pdf.PdfDocument;
import com.spire.pdf.PdfPageBase;
import com.spire.pdf.graphics.PdfCanvas;
import com.spire.pdf.graphics.PdfImage;
import com.spire.pdf.graphics.PdfRGBColor;
import com.spire.pdf.graphics.PdfSolidBrush;
import com.spire.pdf.graphics.PdfTilingBrush;
import com.spire.pdf.graphics.PdfTrueTypeFont;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.stylefeng.roses.kernel.rule.constants.WaterMarkConstant;
import lombok.extern.log4j.Log4j2;
@Log4j2
public class WaterMarkUtil {
public static void main(String[] args) throws Exception {
//要添加的水印图片,图片不要太大,不然会把源文件都覆盖了
byte[] picStream = FileUtil.readBytes("D:\\Users\\Desktop\\temp\\a.png");
String sourcePath = "D:\\Users\\Desktop\\temp\\aa.pdf";
String picOutputPath = "D:\\Users\\Desktop\\temp\\aa_pic_wm.pdf";
String textOutputPath = "D:\\Users\\Desktop\\temp\\aa_text_wm.pdf";
//添加图片水印
addPicWatermark(sourcePath, new ByteArrayInputStream(picStream), picOutputPath, PositionEnum.LEFTTOP.getValue(),100);
String text = "hello word";
addTextWatermark(sourcePath, text, textOutputPath, 100, 0, 20, "#000000", PositionEnum.GRID.getValue());
}
/**
* 添加图片水印
* @author lsy
* @param originFilePath 源pdf文件路径
* @param watermarkFileStream 水印图片流
* @param outputPath 输出文件路径
* @param position 位置
* @param opacity 透明度
* @throws IOException
*/
public static void addPicWatermark(String originFilePath, InputStream watermarkFileStream, String outputPath, String position, Integer opacity) throws IOException {
//创建PdfDocument对象,并加载PDF测试文档
PdfDocument pdf = new PdfDocument();
pdf.loadFromFile(originFilePath);
try {
PdfImage image = PdfImage.fromStream(watermarkFileStream);
//遍历文档每一页,加载图片,并设置成平铺背景(水印)
for (int i = 0; i < pdf.getPages().getCount(); i++) {
PdfPageBase page = pdf.getPages().get(i);
PdfCanvas canvas = page.getCanvas();
canvas.setTransparency(Double.valueOf(opacity)/100);
double fileWidth = canvas.getSize().getWidth();
double fileHeight = canvas.getSize().getHeight();
double imageWidth = image.getWidth();
double imageHeight = image.getHeight();
double[] coordinate = getTextCoordinate(position, 0, fileWidth, fileHeight, imageWidth, imageHeight);
if(WaterMarkConstant.PositionEnum.GRID.getValue().equals(position)) {
imageWidth = fileWidth;
imageHeight = fileHeight;
}
canvas.drawImage(image, coordinate[0], coordinate[1], imageWidth, imageHeight);
}
//保存文档
pdf.saveToFile(outputPath);
} catch (Exception e) {
log.error("添加图片水印异常",e);
} finally {
pdf.dispose();
if(null != watermarkFileStream) {
watermarkFileStream.close();
}
}
}
/**
* 添加文字水印
* @author lsy
* @param originFilePath 源pdf文件路径
* @param watermark 水印文本
* @param outputPath 输出文件路径
* @param opacity 透明度
* @param angle 角度
* @param frontSize 字体大小
* @param frontColor 字体颜色
* @param position 位置
*/
public static void addTextWatermark(String originFilePath, String watermark,String outputPath, Integer opacity, Integer angle, Integer frontSize, String frontColor, String position) {
PdfDocument pdf = new PdfDocument();
try {
pdf.loadFromFile(originFilePath);
PdfTrueTypeFont font = new PdfTrueTypeFont(ResourceUtil.getStream("fonts/msyh.ttf"), frontSize);
double width = font.measureString(watermark).getWidth();
double height = font.measureString(watermark).getHeight();
PdfSolidBrush solidBrush = new PdfSolidBrush(new PdfRGBColor(Color.decode(frontColor)));
for (int i = 0; i < pdf.getPages().getCount(); i++){
//获取一个页面
PdfPageBase page = pdf.getPages().get(i);
double fileWidth = page.getCanvas().getSize().getWidth();
double fileHeight = page.getCanvas().getSize().getHeight();
//设置偏移量
if(WaterMarkConstant.PositionEnum.GRID.getValue().equals(position)) {
double set1 = width * Math.sqrt(2) / 4;
double set2 = height * Math.sqrt(2) / 4;
//创建一个平铺笔刷
PdfTilingBrush brush = new PdfTilingBrush(new Dimension((int) (page.getActualSize().getWidth()/3), (int) (page.getActualSize().getHeight()/3)));
brush.getGraphics().setTransparency(Double.valueOf(opacity)/100);
brush.getGraphics().save();
brush.getGraphics().translateTransform(brush.getSize().getWidth()/2 - set1 - set2, brush.getSize().getHeight()/2 + set1 - set2);
brush.getGraphics().rotateTransform(angle);
//绘制水印文本到平铺笔刷
brush.getGraphics().drawString(watermark, font, solidBrush, 0, 0);
brush.getGraphics().restore();
//使用该平铺笔刷绘制水印
page.getCanvas().drawRectangle(brush, new Rectangle(new Point(0, 0), new Dimension((int)(page.getActualSize().getWidth()), (int)(page.getActualSize().getHeight()))));
}else {
double[] coordinate = getTextCoordinate(position, angle, fileWidth, fileHeight, width, height);
page.getCanvas().setTransparency(Double.valueOf(opacity)/100);//透明度
page.getCanvas().translateTransform(coordinate[0], coordinate[1]);//偏移量
page.getCanvas().rotateTransform(angle);//旋转角度
//将水印绘制在该页面上
page.getCanvas().drawString(watermark, font, solidBrush, 0, 0);
}
}
// 保存文档
pdf.saveToFile(outputPath);
} catch (Exception e) {
} finally {
pdf.dispose();
}
}
public static double[] getTextCoordinate(String position,Integer angle, double fileWidth, double fileHeight, double textWidth, double textHeight) {
double[] coordinate = {0.0, 0.0};
if(WaterMarkConstant.PositionEnum.LEFTTOP.getValue().equals(position) || WaterMarkConstant.PositionEnum.GRID.getValue().equals(position)) {
if(180 != Math.abs(angle)) {
coordinate[0] = 0.0;
coordinate[1] = 0.0;
}else {
coordinate[0] = textWidth;
coordinate[1] = textHeight;
}
}else if(WaterMarkConstant.PositionEnum.RIGHTTOP.getValue().equals(position)) {
if(180 != Math.abs(angle)) {
coordinate[0] = fileWidth - textWidth;
coordinate[1] = 0.0;
}else {
coordinate[0] = fileWidth;
coordinate[1] = textHeight;
}
}else if(WaterMarkConstant.PositionEnum.LEFTBOTTOM.getValue().equals(position)) {
if(180 != Math.abs(angle)) {
coordinate[0] = 0.0;
coordinate[1] = fileHeight - textHeight;
}else {
coordinate[0] = textWidth;
coordinate[1] = fileHeight;
}
}else if(WaterMarkConstant.PositionEnum.RIGHTBOTTOM.getValue().equals(position)) {
if(180 != Math.abs(angle)) {
coordinate[0] = fileWidth - textWidth;
coordinate[1] = fileHeight - textHeight;
}else {
coordinate[0] = fileWidth;
coordinate[1] = fileHeight;
}
}else if(WaterMarkConstant.PositionEnum.CENTER.getValue().equals(position)) {
coordinate[0] = ( fileWidth - textWidth ) / 2;
coordinate[1] = ( fileHeight - textHeight ) / 2;
}else if(WaterMarkConstant.PositionEnum.GRID.getValue().equals(position)) {
coordinate[0] = 0.0;
coordinate[1] = 0.0;
}
return coordinate;
}
public enum PositionEnum {
LEFTTOP("leftTop", "左上"),
RIGHTTOP("rightTop", "右上"),
LEFTBOTTOM("leftBottom", "左下"),
RIGHTBOTTOM("rightBottom", "右下"),
CENTER("center", "居中"),
GRID("grid", "全铺"),
;
private String value;
private String desc;
PositionEnum(String value, String desc) {
this.value = value;
this.desc = desc;
}
public String getValue() {
return value;
}
public String getDesc() {
return desc;
}
}
}