To add an image watermark in Java, open the source PDF, load the logo, draw it on each target page inside that page’s visible CropBox (or MediaBox), and save a new file. iText 7 offers convenient opacity and transformation controls; Apache PDFBox provides direct, lower-level content-stream control. The examples below watermark every page, handle mixed page sizes, and explain why a watermark can exist in the file yet remain invisible.
Choose the library before you write code
| Concern | iText 7 | Apache PDFBox |
|---|---|---|
| Watermark workflow | Official transparent-image examples use ImageData, PdfExtGState, PdfCanvas, page iteration and an image transformation matrix. |
Official AddImageToPDF example uses PDImageXObject and PDPageContentStream in append mode. |
| Transparency | Set opacity directly with PdfExtGState. |
Use the content stream’s graphics-state operations explicitly. |
| Placement and transforms | High-level APIs plus matrix-based placement. | Direct drawImage coordinates and dimensions. |
| Best fit | Teams wanting documented composition and watermark patterns. | Teams wanting an Apache open-source library and direct stream control. |
| Before shipping | Confirm the current iText license and any commercial obligations for your distribution. | Confirm the API details for the PDFBox version selected. |
Both libraries can produce a valid watermark. Your decision should be based on licensing, the amount of transform control you need, and how much low-level PDF content-stream work your team wants to maintain.
iText 7: watermark every page
This complete example reads input.pdf, loads logo.png, computes a size that fits each page, centers the logo, applies 50% opacity, and writes watermarked.pdf. It uses the CropBox when available and falls back to the MediaBox.
import com.itextpdf.io.image.ImageData;
import com.itextpdf.io.image.ImageDataFactory;
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.extgstate.PdfExtGState;
public class ImageWatermark {
public static void main(String[] args) throws Exception {
String input = "input.pdf";
String output = "watermarked.pdf";
String imagePath = "logo.png";
ImageData image = ImageDataFactory.create(imagePath);
PdfExtGState opacity = new PdfExtGState().setFillOpacity(0.5f);
try (PdfDocument pdf = new PdfDocument(
new PdfReader(input), new PdfWriter(output))) {
for (int pageNumber = 1; pageNumber <= pdf.getNumberOfPages(); pageNumber++) {
PdfPage page = pdf.getPage(pageNumber);
Rectangle box = page.getCropBox();
if (box == null) {
box = page.getMediaBox();
}
float pageWidth = box.getWidth();
float pageHeight = box.getHeight();
float maxWidth = pageWidth * 0.35f;
float maxHeight = pageHeight * 0.35f;
float scale = Math.min(maxWidth / image.getWidth(),
maxHeight / image.getHeight());
float width = image.getWidth() * scale;
float height = image.getHeight() * scale;
float x = box.getLeft() + (pageWidth - width) / 2f;
float y = box.getBottom() + (pageHeight - height) / 2f;
PdfCanvas canvas = new PdfCanvas(page);
canvas.saveState();
canvas.setExtGState(opacity);
canvas.addImageWithTransformationMatrix(
image, width, 0, 0, height, x, y, false);
canvas.restoreState();
}
}
}
}
Why each part matters
ImageDataFactory.createdecodes the source image once, so the same object can be reused for every page.- The CropBox is the visible rectangle in most viewers. Its left and bottom values may not be zero, so include them in the final coordinates.
- The scale calculation preserves the logo’s aspect ratio and limits it to 35% of both page dimensions.
saveState()andrestoreState()prevent opacity or transforms from leaking into existing or later page content.- The example draws after existing content, so the watermark overlays the page. To place it beneath existing content, write it in the page’s before-content area using the ordering supported by your iText version.
Rotated pages in iText
PDF rotation is metadata, not always a change to the underlying MediaBox dimensions. If visual orientation is your reference, use page.getPageSizeWithRotation() when calculating placement. If you intentionally want the unrotated box, use getPageSize() and handle rotation yourself. Test pages containing 90-degree rotation, because a portrait box with a rotation flag can display as landscape.
Recommended Free Tools
Apache PDFBox: append an image to every page
PDFBox’s documented mechanics are to create a PDImageXObject, open a PDPageContentStream in AppendMode.APPEND, call drawImage, and save. The following extends that pattern to every page and scales the logo to fit each page.
import java.io.File;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.PDPageContentStream.AppendMode;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
public class PdfBoxImageWatermark {
public static void main(String[] args) throws Exception {
File input = new File("input.pdf");
File output = new File("watermarked.pdf");
File logo = new File("logo.png");
try (PDDocument document = PDDocument.load(input)) {
PDImageXObject image = PDImageXObject.createFromFileByContent(logo, document);
for (PDPage page : document.getPages()) {
PDRectangle box = page.getCropBox();
if (box == null) {
box = page.getMediaBox();
}
float maxWidth = box.getWidth() * 0.35f;
float maxHeight = box.getHeight() * 0.35f;
float scale = Math.min(maxWidth / image.getWidth(),
maxHeight / image.getHeight());
float width = image.getWidth() * scale;
float height = image.getHeight() * scale;
float x = box.getLowerLeftX() + (box.getWidth() - width) / 2f;
float y = box.getLowerLeftY() + (box.getHeight() - height) / 2f;
try (PDPageContentStream stream = new PDPageContentStream(
document, page, AppendMode.APPEND, true, true)) {
stream.drawImage(image, x, y, width, height);
}
}
document.save(output);
}
}
}
PDFBox’s basic example demonstrates the first page; looping over document.getPages() applies the same operation to all pages. Verify the result with portrait, landscape and rotated input. The exact constructor and image-loading method can vary between PDFBox releases, so compile against the version declared by your build.
Transparency and ordering in PDFBox
drawImage places the image in the appended stream, normally above existing content. For a translucent logo, configure the content stream’s graphics state with the PDFBox API available in your selected release, then restore it after drawing. If the mark must sit behind text, use the library’s prepend/before-content ordering rather than append mode.
Rank #2
Coordinates, scaling and page geometry
Use the visible page rectangle
PDF coordinates are measured from the lower-left corner. A nonzero CropBox origin means that (0, 0) may be outside the visible page. Compute positions from left + (width - imageWidth)/2 and bottom + (height - imageHeight)/2. When no CropBox is defined, use the MediaBox.
Choose a predictable size
Never use the source pixel dimensions as PDF points without a limit. Constrain width and height, then choose the smaller scale factor so the complete logo remains visible. For a corner watermark, set a margin and use the page’s left/bottom coordinates; for a diagonal mark, calculate a transformation matrix and allow extra bounds for the rotated image.
Images with transparency
PNG alpha can preserve transparent areas, but image transparency and overall watermark opacity are separate concerns. Test a light logo on a dark page and a dark logo on a light page. A fully transparent source or an opacity value near zero can make a correctly placed image appear absent.
Validation and troubleshooting
The PDF grew, but no watermark is visible
- Log the page box, image width and image height. Confirm
xthroughx + widthandythroughy + heightlie inside the CropBox or MediaBox. - Check page rotation. A rotated page can display a different orientation from its stored dimensions.
- Temporarily set opacity to 1 and use a solid, contrasting test image.
- Open the output in a second PDF viewer. Viewer rendering differences can expose clipping or transparency issues.
Only some pages are marked
Make sure the loop uses the document’s actual page count or page collection, not a hard-coded page number. Mixed page sizes require recalculating coordinates for every page.
The logo is clipped
Reduce the scale, account for nonzero box origins, and inspect the CropBox rather than assuming the MediaBox is visible. A rotated image also needs bounds large enough for its corners.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Existing content changes unexpectedly
In iText, wrap changes in saveState/restoreState. In PDFBox, close each content stream and restore any graphics-state settings. Do not leave a transform or opacity active for subsequent operations.
Rank #4
The output cannot be opened
Write to a new path rather than overwriting the input while it is open, close the document in a try-with-resources block, and ensure the process has permission to create the output file. Test with a small PDF before processing a batch.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Operational considerations
- I/O: watermarking rewrites the PDF, so disk space must cover the output and temporary processing needs.
- Memory: large scanned PDFs and high-resolution logos increase memory pressure. Reuse one decoded image object and constrain its displayed size.
- Batch jobs: process one document per task, record input/output names and page counts, and verify that each output opens before replacing an original.
- Security: treat PDFs and images as untrusted input, keep dependencies current, and isolate automated processing where appropriate.
- Quality: test CropBox offsets, MediaBox fallback, mixed dimensions, rotation, transparency, encrypted files and pages with existing annotations.
Or skip the browser setup
If your workflow starts with web pages rather than local PDFs, ScreenshotNeo can return a clean screenshot or PDF from one GET request. Its capture process accepts cookie/consent banners and removes more than 60 known consent platforms, newsletter popups and chat widgets before the shot; bot checks, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing status. It also provides an MCP server with take_screenshot, get_page_info and capture_pdf for Claude, Cursor and other MCP clients.
See the ScreenshotNeo API documentation for all options. A direct call is:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
The free plan includes 1,000 screenshots each month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
Best Value
Frequently Asked Questions
Can I watermark only selected pages?
Yes. Replace the all-pages loop with a loop over the page numbers you want, while retaining the same box, scale and placement calculations.
Should the watermark be above or below the PDF content?
Appending draws above existing content; use the library’s prepend or before-content mechanism when the mark should sit underneath.
Can I use a PDF page as the watermark image?
The examples load raster images. A PDF page must first be rendered to an image or placed using a dedicated PDF-form/XObject workflow.
Why does a rotated page still look misaligned after using its visual size?
Rotation metadata and box coordinates can interact with viewer behavior. Inspect the page rotation, CropBox origin and final bounds together, then test in more than one viewer.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




