html
复制代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>PDF Watermark Example</title>
<script src="https://cdn.bootcdn.net/ajax/libs/pdf-lib/1.17.1/pdf-lib.min.js"></script>
</head>
<body>
<input type="file" id="pdfFile" accept="application/pdf">
<button onclick="addWatermark()">添加水印</button>
<a id="downloadLink" style="display:none;">下载PDF</a>
<script>
async function addWatermark() {
const fileInput = document.getElementById('pdfFile');
const file = fileInput.files[0];
if (!file) {
alert('请选择一个PDF文件');
return;
}
const arrayBuffer = await file.arrayBuffer();
const pdfDoc = await PDFLib.PDFDocument.load(arrayBuffer);
const pages = pdfDoc.getPages();
// 获取当前时间并格式化
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0');
const day = String(now.getDate()).padStart(2, '0');
const hour = String(now.getHours()).padStart(2, '0');
const minute = String(now.getMinutes()).padStart(2, '0');
// 创建水印
const watermarkText = `无敌暴龙兽-${year}-${month}-${day}-${hour}:${minute}-加密`;
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const fontSize = 20;
const textColor = 'rgba(0, 0, 0, 0.2)';
// 计算文本宽度和高度
ctx.font = `${fontSize}px Arial`;
const textMetrics = ctx.measureText(watermarkText);
const textWidth = textMetrics.width;
const textHeight = fontSize;
// 计算旋转后的文本边界
const angle = -Math.PI / 4; // 旋转45度
const rotatedWidth = Math.abs(textWidth * Math.cos(angle)) + Math.abs(textHeight * Math.sin(angle));
const rotatedHeight = Math.abs(textHeight * Math.cos(angle)) + Math.abs(textWidth * Math.sin(angle));
// 设置Canvas大小
canvas.width = rotatedWidth + 20; // 增加一些边距
canvas.height = rotatedHeight + 20;
// 绘制水印文本
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.rotate(angle);
ctx.font = `${fontSize}px Arial`;
ctx.fillStyle = textColor;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(watermarkText, 0, 0);
// 将Canvas转换为Image对象
const image = new Image();
image.src = canvas.toDataURL('image/png');
// 添加水印到每一页PDF
for (const page of pages) {
const { width, height } = page.getSize();
// 计算新的水印尺寸,以便它可以跨越页面的两个相邻边缘
const cornerMargin = 50; // 角落与页面边缘之间的最小距离
const cornerSizeMultiplier = 0.5; // 控制水印相对于页面尺寸的比例
const scale = 1; // 水印缩放比例
const cornerWidth = Math.min(width, height) * cornerSizeMultiplier * scale;
const cornerHeight = cornerWidth; // 假设是正方形水印
// 计算水印的新位置,使其跨越页面的两个相邻边缘
const positions = [
{ x: cornerMargin, y: cornerMargin }, // 左上角
{ x: width - cornerWidth - cornerMargin, y: cornerMargin }, // 右上角
{ x: cornerMargin, y: height - cornerHeight - cornerMargin }, // 左下角
{ x: width - cornerWidth - cornerMargin, y: height - cornerHeight - cornerMargin } // 右下角
];
// 需要重新创建水印图像以匹配新尺寸
const newCanvas = document.createElement('canvas');
const newCtx = newCanvas.getContext('2d');
newCanvas.width = cornerWidth;
newCanvas.height = cornerHeight;
// 复制旧水印到新画布
newCtx.drawImage(canvas, 0, 0, cornerWidth, cornerHeight);
// 将新画布转换回Image对象
const newImage = new Image();
newImage.src = newCanvas.toDataURL('image/png');
// 嵌入新水印到PDF文档
const newImg = await pdfDoc.embedPng(newImage.src);
for (const pos of positions) {
page.drawImage(newImg, {
x: pos.x,
y: pos.y,
width: newImg.width,
height: newImg.height,
});
}
}
// 保存修改后的PDF
const pdfDataUri = await pdfDoc.saveAsBase64({ dataUri: true });
const downloadLink = document.getElementById('downloadLink');
downloadLink.href = pdfDataUri;
downloadLink.download = 'watermarked.pdf';
downloadLink.click();
}
</script>
</body>
</html>