【发布时间】:2016-10-26 16:35:55
【问题描述】:
我在 Java 8 Spring Boot 应用程序中使用 PDFBox 2.1.0-SNAPSHOT 在原本只有图像的 PDF 文档的每一页上添加透明文本水印。从视觉上看,它工作得很好,因为我可以通过任何阅读器和所有浏览器内联 PDF 查看器上的水印看到图像。
但是,当我从 IE 打印这些文档时,不透明的白色背景会覆盖文本后面的图像。水印文字依然是透明的,但是文字的边框是白色的。同样,从所有其他浏览器打印都可以正常工作。 (一定喜欢 IE。)
这是我用来将水印添加到每个页面的代码:
public void watermark(File pdfFile, OutputStream output) throws IOException {
try (final InputStream sourceStream = new FileInputStream(pdfFile);
final PDDocument document = PDDocument.load(sourceStream)) {
for (int pageNumber = 0; pageNumber < document.getNumberOfPages(); pageNumber++) {
PDPage currPage = document.getPage(pageNumber);
writeWatermarkOnPage(document, currPage);
}
document.save(output);
}
}
private void writeWatermarkOnPage(PDDocument document, PDPage page) throws IOException {
try (PDPageContentStream contentStream = new PDPageContentStream(
document, page, PDPageContentStream.AppendMode.APPEND, true, true)) {
PDRectangle rect = page.getBBox();
// Set the opacity
PDExtendedGraphicsState extendedGraphicsState = new PDExtendedGraphicsState();
extendedGraphicsState.setNonStrokingAlphaConstant(0.3f);
contentStream.setGraphicsStateParameters(extendedGraphicsState);
// Add the text
contentStream.beginText();
contentStream.setFont(PDType1Font.HELVETICA_BOLD, 75);
contentStream.setNonStrokingColor(Color.GRAY);
AffineTransform at = new AffineTransform(1, 0, 0, 1,
rect.getUpperRightX() / 4,
rect.getUpperRightY() / 4);
Matrix matrix = new Matrix(at);
matrix.rotate(Math.toRadians(45));
contentStream.setTextMatrix(matrix);
contentStream.showText("WATERMARK-TEXT");
contentStream.endText();
}
}
我尝试使用 Overlay 类,但结果相同。我尝试删除旋转和变换,但这没有帮助。只有当我删除 nonStrokingAlphaConstant 设置时,从 IE 的内联 PDF 渲染器打印时,不透明的白色背景才会消失,但文本不再透明。
我还需要做些什么来告诉每个上下文中的每个 PDF 阅读器文本的背景应该是完全透明的吗?
更新
这是一个示例PDF Document that shows this behavior。在 Windows 上,我只需将其拖放到 IE 中,打印它,水印文本的白色背景就会覆盖底层图像。
这是来自 IE 的另一个示例 PDF created and watermarked with the same code that actually prints just fine。水印是透明的,没有白色背景。
我认为不同之处在于损坏的文档是合法大小的图像,而工作文档是字母大小。也许与缩放有关的东西导致了这个问题?
【问题讨论】:
-
1) 从 Adobe Reader 打印可以吗? 2) MSIE 中用于显示/打印 PDF 的程序是什么?
-
是的,@Tilman,如果我从独立的 Adobe Reader DC 打印就可以了,这很奇怪。在 MSIE 中,它使用 Adobe Reader 来显示/打印 PDF。
-
请分享一个可以观察到问题的示例 pdf。
-
@mkl,我在后期更新中添加了示例 PDF 文档和更多测试结果。
-
@Tilman 我刚刚发现了一个解决方法:如果我创建一个具有透明背景的 PNG 并用透明度覆盖它,它就可以正常工作并打印。如果没有办法使用文本,我可能会继续前进。完成后我会发布代码。