Add Watermark to PDF Document using iText and Java
A watermark is a kind of marker – or stamp -, and usually is text or an image embedded either in front of, or behind the content of the pdf document. It is used to verify the authenticity and integrity of the document, verify ownership and for tracing copyright infringements. In this tutorial we show how to add a watermark to either a new or existing existing PDF document using iText and Java.
Add Watermark to New PDF Document using Page Events
The easiest way to add a watermark to a new PDF document, is by using Page Events. We can extend fromPdfPageEventHelper
and override the onEndPage
method. This page event is fired by iText when the writer is at the end of the page, and thus the ideal page to write a watermark. We write text using the ColumnText.showTextAligned()
method, passing in the PdfContentByte
obtained from writer.getDirectContentUnder()
as the first argument. The second argument is the alignment. In the third argument, we pass in the Phrase
, which is the actual text. The fourth and fifth arguments are the x and y positions, respectively. The sixth and last argument is the rotation of the text.
package com.memorynotfound.pdf.itext;
import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.GrayColor;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfWriter;
public class WatermarkPageEvent extends PdfPageEventHelper {
Font FONT = new Font(Font.FontFamily.HELVETICA, 52, Font.BOLD, new GrayColor(0.85f));
@Override
public void onEndPage(PdfWriter writer, Document document) {
ColumnText.showTextAligned(writer.getDirectContentUnder(),
Element.ALIGN_CENTER, new Phrase("Memorynotfound.com", FONT),
297.5f, 421, writer.getPageNumber() % 2 == 1 ? 45 : -45);
}
}
In a previous tutorial we saw how to create pdf document using itext. This example also creates a PDF document, but instead we include page events. We add the previously created WatermarkPageEvent
using the PdfWriter#setPageEvent
method. Itext will invoke the page events and afterwards the watermark is added to the pdf document.
package com.memorynotfound.pdf.itext;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfWriter;
import java.io.FileOutputStream;
import java.io.IOException;
public class WatermarkPdf {
public static void main(String... args) throws IOException, DocumentException {
// create document
Document document = new Document(PageSize.A4, 36, 36, 90, 36);
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("watermark.pdf"));
// add header and footer
writer.setPageEvent(new WatermarkPageEvent());
// write to document
document.open();
document.add(new Paragraph("Testing."));
document.newPage();
document.add(new Paragraph("Testing."));
document.newPage();
document.close();
}
}
Demo
The following demo is the resulting document. We added a watermark to a new pdf document.
Add Watermark to Existing PDF Document
Sometimes the procedure of watermarking is separate from the creation of new PDF documents. In that case, we need to add a watermark to an existing PDF document. The following example demonstrates how to add a watermark to an existing PDF document. This code also show how to add an image, or a logo as a watermark. Let’s see what’s happening:
- We start by reading the existing PDF using the
PdfReader
. - The
PdfStamper
is used to write additional data to the pdf document. We initialize it with an instance of thePdfReader
as the first argument, followed by anFileOutputStream
as the second argument. ThisOutputStream
will write the new PDF document to disk. - Next, we create a
phrase
. The first argument is the text that’ll be displayed. The second argument is the font that’ll be used for that phrase. - We can also add an image, or logo as the watermark. We create a new
Image
instance and load the image from thesrc/main/resources
folder. - We loop over each page, and:
- Calculate the dead center of the page. These x and y positions will be used to position the text and image on the PDF document.
- Using the
PdfGState
, we can set the transparency – or opacity – of the watermark. - On even pages, we display an image, or logo. Uneven pages receive a text.
- Finally, we close the
PdfStamper
andPdfReader
and afterwards, the document is written to disk.
package com.memorynotfound.pdf.itext;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
public class WatermarkPdf {
public static void main(String... args) throws IOException, DocumentException {
// read existing pdf
PdfReader reader = new PdfReader(getResource("/example.pdf"));
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("watermarked.pdf"));
// text watermark
Font FONT = new Font(Font.FontFamily.HELVETICA, 34, Font.BOLD, new GrayColor(0.5f));
Phrase p = new Phrase("Memorynotfound (watermark)", FONT);
// image watermark
Image img = Image.getInstance(getResource("/memorynotfound-logo.jpg"));
float w = img.getScaledWidth();
float h = img.getScaledHeight();
// properties
PdfContentByte over;
Rectangle pagesize;
float x, y;
// loop over every page
int n = reader.getNumberOfPages();
for (int i = 1; i <= n; i++) {
// get page size and position
pagesize = reader.getPageSizeWithRotation(i);
x = (pagesize.getLeft() + pagesize.getRight()) / 2;
y = (pagesize.getTop() + pagesize.getBottom()) / 2;
over = stamper.getOverContent(i);
over.saveState();
// set transparency
PdfGState state = new PdfGState();
state.setFillOpacity(0.2f);
over.setGState(state);
// add watermark text and image
if (i % 2 == 1) {
ColumnText.showTextAligned(over, Element.ALIGN_CENTER, p, x, y, 0);
} else {
over.addImage(img, w, 0, 0, h, x - (w / 2), y - (h / 2));
}
over.restoreState();
}
stamper.close();
reader.close();
}
private static URL getResource(String name){
return WatermarkPdf.class.getResource(name);
}
}