我试图在pdf中使用itext添加水印。使用以下代码可以正常工作:
import com.itextpdf.io.font.constants.StandardFonts;
import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.colors.PatternColor;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.kernel.pdf.canvas.PdfPatternCanvas;
import com.itextpdf.kernel.pdf.colorspace.PdfPattern;
import com.itextpdf.kernel.pdf.colorspace.PdfPattern.Tiling;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.element.Paragraph;
public class TestNewPdf {
@SuppressWarnings("resource")
public static void main(String[] args) throws Exception {
PdfReader reader = new PdfReader("F:/barcode/test.pdf");
PdfWriter writer = new PdfWriter("F:/barcode/outputTest.pdf");
PdfDocument pdfDocument = new PdfDocument(reader,writer);
PdfPattern.Tiling tiling = new Tiling(new Rectangle(220, 100));
new Canvas(new PdfPatternCanvas(tiling, pdfDocument), pdfDocument, tiling.getBBox()).add(new Paragraph("franco")
.setFontColor(ColorConstants.RED)
.setBold()
.setFont(PdfFontFactory.createFont(StandardFonts.HELVETICA_BOLD))
.setFontSize(10f)
.setRotationAngle(Math.PI / 10)
);
for (int i = 1; i <= pdfDocument.getNumberOfPages(); i++) {
PdfPage page = pdfDocument.getPage(i);
new PdfCanvas(page.newContentStreamBefore(), page.getResources(), pdfDocument)
.saveState()
.setFillColor(new PatternColor(tiling))
.rectangle(page.getCropBox())
.fill()
.restoreState();
}
pdfDocument.close();
}
}但是,当源pdf包含图像或源pdf是扫描文件时,我有一个问题,这意味着pdf变得像图像。
水印文本隐藏在图像后面。
有人能帮我解决这个问题吗?
更新:
在某些情况下,水印覆盖内容,如何使文本更加透明。我对代码进行了更新,但没有成功,以使水印更加透明。
我试着用这个代码:
PdfFont helvetica = PdfFontFactory.createFont();
PdfDocument pdfDocument = new PdfDocument(reader,writer);
PdfPattern.Tiling tiling = new Tiling(new Rectangle(220, 100));
new Canvas(new PdfPatternCanvas(tiling, pdfDocument), pdfDocument, tiling.getBBox()).add(new Paragraph("uhatem")
.setFontColor(ColorConstants.GRAY)
.setFont(helvetica)
.setFontSize(15f)
.setRotationAngle(Math.PI / 10)
);
for (int i = 1; i <= pdfDocument.getNumberOfPages(); i++) {
PdfPage page = pdfDocument.getPage(i);
new PdfCanvas(page.newContentStreamAfter(), page.getResources(), pdfDocument)
.saveState()
.setFillColor(new PatternColor(tiling))
.rectangle(page.getCropBox())
.fill()
.restoreState();
}
pdfDocument.close();发布于 2022-01-02 11:03:24
您可以使用page.newContentStreamBefore()为您的水标记添加内容流。因此,在绘制页面时,首先绘制水印,然后在其上绘制内容。对于通常的文本和稀疏矢量图形,这是好的,但对于覆盖内容的全部区域,水印可能是完全隐藏的。
尝试使用page.newContentStreamAfter()代替。但是要小心,你可能不想再加粗的水印文本了,甚至可能只限于大纲,因为标记现在涵盖了内容。
在问题更新和评论中,您询问了如何
使文本透明。
透明度通常是通过选择匹配的扩展图形状态来实现的,例如:
PdfExtGState extGState = new PdfExtGState().setBlendMode(new PdfName("Multiply"));
for (int i = 1; i <= pdfDocument.getNumberOfPages(); i++) {
PdfPage page = pdfDocument.getPage(i);
new PdfCanvas(page.newContentStreamAfter(), page.getResources(), pdfDocument)
.saveState()
.setExtGState(extGState)
.setFillColor(new PatternColor(tiling))
.rectangle(page.getCropBox())
.fill()
.restoreState();(https://github.com/mkl-public/testarea-itext7/blob/master/src/test/java/mkl/testarea/itext7/content/AddWatermark.java#L87 test testAddLikeFrancoImproved__)
您可以尝试找出您想要使用混合模式(这里的示例中是“乘”)还是alpha值透明度(使用setFillOpacity和setStrokeOpacity而不是setBlendMode设置)
https://stackoverflow.com/questions/70554618
复制相似问题