I try to add a watermark using itext in pdf. it work without problem using this code :
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();
}
}
but I have a problem for specific case when the source pdf contain image or the source pdf is a scanning file meaning the pdf become like image .
the watermark text is hiding behind images
can someone help me to resolve this problem
updated :
In some case the watermark cover content, how can I make the text more transparent . I have update my code without success to make the watermark more transparent
I try with this code :
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();
You use page.newContentStreamBefore()
to add a content stream for your water mark. Thus, when the page is drawn, the watermark is drawn first and the content thereafter over it. For usual text and sparse vector graphics that is good but for full area covering content the watermark may be totally hidden.
Try to use page.newContentStreamAfter()
instead. But beware, you may not want to bold the watermark text then anymore, probably even restrict to outline only, as the mark now covers content.
In a question update and a comment you asked how to
make the text transparent.
Transparency usually is achieved by selecting a matching extended graphics state, e.g.:
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();
(AddWatermark test testAddLikeFrancoImproved
)
You can try and find out whether you want to use a blend mode (like "Multiply" in the example here) or alpha value transparency (set using setFillOpacity
and setStrokeOpacity
instead of setBlendMode
)