使用Aspose.Total for Java实现PDF不可选中可见背景水印的问题
解决方案
方案一:文本转透明图片后插入ImageStamp(适配17.10版本,无兼容性问题)
将水印文本先渲染为带透明度的PNG图片,再通过ImageStamp添加到PDF,生成的水印天生不可选中,旋转、尺寸、透明度均可自由调整,显示效果清晰。
代码示例:
private byte[] addWatermarkToPdf(byte[] data) throws Exception { com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(new ByteArrayInputStream(data)); ByteArrayOutputStream output = new ByteArrayOutputStream(); // 第一步:生成水印文本的透明背景图片 int imgWidth = 600; int imgHeight = 150; BufferedImage watermarkImg = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = watermarkImg.createGraphics(); // 启用抗锯齿提升清晰度 g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); g2d.setComposite(AlphaComposite.Clear); g2d.fillRect(0, 0, imgWidth, imgHeight); g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f)); g2d.setColor(new Color(222, 222, 222)); g2d.setFont(Font.createFont(Font.TRUETYPE_FONT, new File("C:\\myFont.ttf")).deriveFont(14f)); // 居中绘制文本 FontMetrics metrics = g2d.getFontMetrics(); int x = (imgWidth - metrics.stringWidth("Watermark text")) / 2; int y = (imgHeight - metrics.getHeight()) / 2 + metrics.getAscent(); g2d.drawString("Watermark text", x, y); g2d.dispose(); // 第二步:将图片转为字节流 ByteArrayOutputStream imgOut = new ByteArrayOutputStream(); ImageIO.write(watermarkImg, "png", imgOut); byte[] imgBytes = imgOut.toByteArray(); // 第三步:创建ImageStamp添加到PDF ImageStamp imageStamp = new ImageStamp(new ByteArrayInputStream(imgBytes)); imageStamp.setBackground(true); imageStamp.setWidth(558.35); imageStamp.setHeight(93.05); imageStamp.setRotateAngle(45); // 对应你之前的-315度效果 imageStamp.setOpacity(0.5); imageStamp.setHorizontalAlignment(HorizontalAlignment.Center); imageStamp.setVerticalAlignment(VerticalAlignment.Center); for (int pageCounter = 1; pageCounter <= pdfDocument.getPages().size(); pageCounter++) { pdfDocument.getPages().get_Item(pageCounter).addStamp(imageStamp); } pdfDocument.save(output, SaveFormat.Pdf); pdfDocument.close(); return output.toByteArray(); }
方案二:升级Aspose.PDF版本(无需转图片)
你使用的17.10版本存在TextStamp渲染模糊、WatermarkAnnotation旋转不生效的已知缺陷,升级到20.6及以上版本后,直接使用WatermarkArtifact并添加只读标记即可实现不可选中的清晰水印:
WatermarkArtifact artifact = new WatermarkArtifact(); artifact.setText(formattedText); artifact.setArtifactHorizontalAlignment(HorizontalAlignment.Center); artifact.setArtifactVerticalAlignment(VerticalAlignment.Center); artifact.setRotation(45); artifact.setOpacity(0.5); artifact.setBackground(true); artifact.setReadOnly(true); // 禁止选中和修改 artifact.setSubtype(Artifact.ArtifactSubtype.Watermark); doc.getPages().get_Item(1).getArtifacts().add(artifact);
之前方案失败原因说明
- 17.10版本的
TextStamp.setDraw(true)底层矢量渲染逻辑存在缺陷,会导致水印文字模糊 - 17.10版本
WatermarkAnnotation的旋转属性存在未修复的bug,自定义旋转角度不会生效 - 所有直接使用文本类水印的方案,在未加特殊标记的情况下,默认会被识别为PDF正文文本,可被选中复制
内容的提问来源于stack exchange,提问作者ppaweluz
相关产品推荐
相关产品推荐

