Java PDF 图片水印实现指南
在Java中为PDF添加图片水印是一个常见的需求,下面我将介绍几种实现方法,包括使用iText和Apache PDFBox等流行库。
使用iText库
iText是一个功能强大的PDF操作库,以下是添加图片水印的示例代码:
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import java.io.FileOutputStream;
public class PdfImageWatermark {
public static void main(String[] args) {
try {
// 1. 创建PDF文档和PdfReader
PdfReader reader = new PdfReader("input.pdf");
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("output_with_watermark.pdf"));
// 2. 加载水印图片
Image watermark = Image.getInstance("watermark.png");
watermark.setAbsolutePosition(100, 100); // 设置水印位置
watermark.setRotation(45); // 设置旋转角度(可选)
watermark.setTransparency(0.5f, 0.5f); // 设置透明度
// 3. 为每一页添加水印
int pageCount = reader.getNumberOfPages();
for (int i = 1; i <= pageCount; i++) {
PdfContentByte content = stamper.getOverContent(i);
content.addImage(watermark);
}
// 4. 关闭资源
stamper.close();
reader.close();
System.out.println("水印添加成功!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
使用Apache PDFBox
PDFBox是Apache提供的另一个PDF操作库,以下是使用PDFBox添加图片水印的示例:
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import java.io.File;
import java.io.IOException;
public class PdfBoxWatermark {
public static void main(String[] args) {
try {
// 1. 加载PDF文档
PDDocument document = PDDocument.load(new File("input.pdf"));
// 2. 加载水印图片
PDImageXObject watermarkImage = PDImageXObject.createFromFile("watermark.png", document);
// 3. 为每一页添加水印
for (PDPage page : document.getPages()) {
try (PDPageContentStream contentStream = new PDPageContentStream(
document, page, PDPageContentStream.AppendMode.APPEND, true)) {
// 设置水印位置和大小
float x = 100;
float y = 100;
float width = 200;
float height = 200;
// 添加水印图片
contentStream.drawImage(watermarkImage, x, y, width, height);
}
}
// 4. 保存并关闭文档
document.save("output_with_watermark.pdf");
document.close();
System.out.println("水印添加成功!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
高级功能实现
添加多页水印
如果需要在每页的特定位置添加水印,可以修改循环逻辑:
// iText示例
for (int i = 1; i <= pageCount; i++) {
PdfContentByte content = stamper.getOverContent(i);
// 计算每页的水印位置
Rectangle pageSize = reader.getPageSize(i);
float x = (pageSize.getWidth() - watermark.getScaledWidth()) / 2;
float y = (pageSize.getHeight() - watermark.getScaledHeight()) / 2;
watermark.setAbsolutePosition(x, y);
content.addImage(watermark);
}
添加透明度控制
// iText示例 watermark.setTransparency(0.3f, 0.3f); // 第一个参数是非透明度,第二个参数是透明度 // PDFBox示例 contentStream.setNonStrokingColor(255, 255, 255, 128); // 设置透明度(ARGB)
添加旋转水印
// iText示例 watermark.setRotation(45); // 旋转45度 // PDFBox示例 contentStream.saveGraphicsState(); contentStream.transform(Matrix.getRotateInstance(Math.toRadians(45), x + width/2, y + height/2)); contentStream.drawImage(watermarkImage, x, y, width, height); contentStream.restoreGraphicsState();
注意事项
- 版权问题:确保你有权使用水印图片
- 性能考虑:对于大型PDF文件,添加水印可能会消耗较多内存
- 路径问题:确保图片路径正确,或者将图片作为资源嵌入
- 版本兼容性:不同版本的iText或PDFBox可能有API差异
依赖配置
Maven依赖 (iText 5.x)
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13.3</version>
</dependency>
Maven依赖 (PDFBox)
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.27</version>
</dependency>
代码可以根据你的具体需求进行调整,如水印位置、大小、透明度等参数。
