How to Apply Custom Watermarks to PDFs in Java
IronPDF enables Java developers to apply custom watermarks to PDF documents using HTML strings with full CSS support, allowing complete control over text, images, opacity, rotation, and positioning for branding or security purposes.
Quickstart: Apply Watermarks to PDFs in Java
- Add IronPDF to your Maven or Gradle project and set your license key
- Load your PDF document using
PdfDocument.fromFile() - Create an HTML string for your watermark (text, image, or both)
- Apply the watermark using
pdf.applyWatermark(watermarkHtml) - Save the watermarked PDF with
pdf.saveAs()
```java :title=QuickStartWatermark.java //:path=/static-assets/pdf/content-code-examples/how-to/custom-watermark/quickstart.java PdfDocument pdf = PdfDocument.fromFile(Paths.get("sample.pdf")); pdf.applyWatermark(""); pdf.saveAs("watermarked.pdf");
Watermarking protects PDF documents and communicates ownership or document status. Common use cases include marking drafts as "Confidential," embedding a company logo on every page, or indicating that a document is pending approval. IronPDF takes an HTML-and-CSS approach, which means any styling you can express in a browser (custom fonts, opacity, rotation, absolute positioning) works identically in a watermark.
This guide covers `text` watermarks, `image` watermarks, opacity and position controls, and advanced stamping with [`TextStamper`](https://ironpdf.com/java/how-to/stamp-text-image-pdf/) and [`ImageStamper`](https://ironpdf.com/java/how-to/stamp-text-image-pdf/). For related PDF manipulation techniques, see the guide on [creating PDFs from HTML in Java](https://ironpdf.com/java/how-to/java-create-pdf-tutorial/) or the overview of [adding backgrounds and foregrounds](https://ironpdf.com/java/how-to/background-foreground/).
<div class="hsg-featured-snippet">
<h3>How to Apply Watermarks in Java</h3>
<ol>
<li><a class="js-modal-open" data-modal-id="download-modal" href="#download-modal">Download the Java library to apply watermarks to PDFs</a></li>
<li>Render a new PDF or load an existing one</li>
<li>Configure the HTML string or image to be used as a watermark</li>
<li>Apply the watermark using the appropriate method</li>
<li>Adjust parameters for opacity, rotation, and location as needed</li>
</ol>
</div>
## How Do I Apply a Text Watermark to a PDF?
Use the `applyWatermark` method to stamp text onto every page of a PDF document. The method accepts an HTML string, so you can style the watermark with any CSS property: font family, size, color, letter spacing, or text shadow. The example below marks a document as "Confidential" in red, which covers the most common audit-trail and access-control scenario.
```java
//:path=/static-assets/pdf/content-code-examples/how-to/custom-watermark/text-watermark.java
import java.io.IOException;
import java.nio.file.Paths;
import com.ironsoftware.ironpdf.License;
import com.ironsoftware.ironpdf.PdfDocument;
public class Main {
public static void main(String[] args) throws IOException {
// Set the license key for IronPDF
License.setLicenseKey("IRONPDF-MYLICENSE-KEY-1EF01");
// Load an existing PDF document from file
PdfDocument pdf = PdfDocument.fromFile(Paths.get("sample.pdf"));
// HTML string defines the watermark appearance via CSS
String watermarkHtml = "<h1 style='color:red;'>Confidential</h1>";
// Apply the watermark to every page
pdf.applyWatermark(watermarkHtml);
// Save the watermarked PDF to a new file
pdf.saveAs("text_watermark.pdf");
}
}
The applyWatermark call adds the watermark to all pages in a single operation. By default, the watermark renders at 50% opacity and is centered on each page. To activate all features of the library, configure your IronPDF license key before any PDF operations. The HTML passed to applyWatermark accepts any valid HTML element, so you can include <div>, <span>, or styled <p> tags for multi-line watermarks.
What Does the Text Watermark Look Like?
The output file text_watermark.pdf shows the word Confidential in red, horizontally and vertically centered on each page. The 50% default opacity keeps document content readable beneath the watermark. For multi-page documents, every page receives the same stamp with no per-page loop required.
transform: rotate(-45deg) scale(1.5).For deeper HTML rendering techniques applicable to watermarks, see the HTML to PDF conversion tutorial.
How Can I Add an Image Watermark to a PDF?
Image watermarks work through the same applyWatermark method by wrapping an <img> tag in the HTML string. PNG files with transparent backgrounds are ideal for logo watermarks because transparency is preserved when the image is composited onto the PDF page. JPEG, GIF, SVG, and BMP formats are also supported.
//:path=/static-assets/pdf/content-code-examples/how-to/custom-watermark/image-watermark.java
import java.io.IOException;
import java.nio.file.Paths;
import com.ironsoftware.ironpdf.License;
import com.ironsoftware.ironpdf.PdfDocument;
public class Main {
public static void main(String[] args) throws IOException {
// Set the license key for IronPDF
License.setLicenseKey("IRONPDF-MYLICENSE-KEY-1EF01");
// Load an existing PDF document from file
PdfDocument pdf = PdfDocument.fromFile(Paths.get("sample.pdf"));
// Reference the image file path relative to the runtime working directory
String watermarkHtml = "<img src='logo.png' style='width:100px;'/>";
// Apply the image watermark to all pages
pdf.applyWatermark(watermarkHtml);
// Save the result
pdf.saveAs("image_watermark.pdf");
}
}
//:path=/static-assets/pdf/content-code-examples/how-to/custom-watermark/image-watermark.java
import java.io.IOException;
import java.nio.file.Paths;
import com.ironsoftware.ironpdf.License;
import com.ironsoftware.ironpdf.PdfDocument;
public class Main {
public static void main(String[] args) throws IOException {
// Set the license key for IronPDF
License.setLicenseKey("IRONPDF-MYLICENSE-KEY-1EF01");
// Load an existing PDF document from file
PdfDocument pdf = PdfDocument.fromFile(Paths.get("sample.pdf"));
// Reference the image file path relative to the runtime working directory
String watermarkHtml = "<img src='logo.png' style='width:100px;'/>";
// Apply the image watermark to all pages
pdf.applyWatermark(watermarkHtml);
// Save the result
pdf.saveAs("image_watermark.pdf");
}
}
CSS properties in the <img> tag control size, position, and transparency:
//:path=/static-assets/pdf/content-code-examples/how-to/custom-watermark/image-watermark-advanced.java
// Apply a 150px logo at 50% opacity, rotated 45 degrees counterclockwise
String advancedWatermarkHtml =
"<img src='logo.png' style='width:150px; opacity:0.5; transform:rotate(-45deg);'/>";
//:path=/static-assets/pdf/content-code-examples/how-to/custom-watermark/image-watermark-advanced.java
// Apply a 150px logo at 50% opacity, rotated 45 degrees counterclockwise
String advancedWatermarkHtml =
"<img src='logo.png' style='width:150px; opacity:0.5; transform:rotate(-45deg);'/>";
The image path must be accessible from the JVM's working directory at runtime. For server deployments, use absolute paths or embed the image as a Base64 data URI inside the src attribute to avoid path resolution issues.
What File Formats Are Supported for Image Watermarks?
IronPDF supports PNG, JPEG, GIF, SVG, and BMP image formats in watermarks. PNG with a transparent background produces the cleanest results for logo watermarks. The output file image_watermark.pdf shows the image at 100 pixels width, centered on each page at 50% default opacity. To extract images from an existing PDF for use in another watermark, see the guide on extracting images from PDFs.
How Do I Control Watermark Opacity and Alignment?
The applyWatermark method accepts opacity and alignment parameters after the HTML string. Opacity is an integer from 0 (fully transparent) to 100 (fully opaque). Values between 20 and 40 work well for most documents, keeping the watermark visible without obscuring body text. The VerticalAlignment and HorizontalAlignment enums control which corner or edge of the page the watermark targets.
//:path=/static-assets/pdf/content-code-examples/how-to/custom-watermark/watermark-opacity-alignment.java
import java.io.IOException;
import java.nio.file.Paths;
import com.ironsoftware.ironpdf.License;
import com.ironsoftware.ironpdf.PdfDocument;
import com.ironsoftware.ironpdf.stamp.HorizontalAlignment;
import com.ironsoftware.ironpdf.stamp.VerticalAlignment;
public class Main {
public static void main(String[] args) throws IOException {
// Set the license key for IronPDF
License.setLicenseKey("IRONPDF-MYLICENSE-KEY-1EF01");
// Load an existing PDF document from file
PdfDocument pdf = PdfDocument.fromFile(Paths.get("sample.pdf"));
// Define the watermark HTML
String watermarkHtml = "<h1 style='color:blue;'>Confidential</h1>";
// Apply at 30% opacity, anchored to the top-left corner of each page
pdf.applyWatermark(watermarkHtml, 30, VerticalAlignment.TOP, HorizontalAlignment.LEFT);
// Save the result
pdf.saveAs("watermark_opacity_alignment.pdf");
}
}
//:path=/static-assets/pdf/content-code-examples/how-to/custom-watermark/watermark-opacity-alignment.java
import java.io.IOException;
import java.nio.file.Paths;
import com.ironsoftware.ironpdf.License;
import com.ironsoftware.ironpdf.PdfDocument;
import com.ironsoftware.ironpdf.stamp.HorizontalAlignment;
import com.ironsoftware.ironpdf.stamp.VerticalAlignment;
public class Main {
public static void main(String[] args) throws IOException {
// Set the license key for IronPDF
License.setLicenseKey("IRONPDF-MYLICENSE-KEY-1EF01");
// Load an existing PDF document from file
PdfDocument pdf = PdfDocument.fromFile(Paths.get("sample.pdf"));
// Define the watermark HTML
String watermarkHtml = "<h1 style='color:blue;'>Confidential</h1>";
// Apply at 30% opacity, anchored to the top-left corner of each page
pdf.applyWatermark(watermarkHtml, 30, VerticalAlignment.TOP, HorizontalAlignment.LEFT);
// Save the result
pdf.saveAs("watermark_opacity_alignment.pdf");
}
}
Combining the three optional parameters gives nine distinct positioning options, one for each intersection of vertical and horizontal alignment. For use cases that require watermarks at multiple positions on the same page, or watermarks applied only to a specific page range, the stamper classes provide finer control. See the backgrounds and foregrounds guide for layered composition techniques.
What Alignment Options Are Available?
The applyWatermark method supports the following alignment constants:
Vertical alignment (VerticalAlignment):
TOP- watermark anchored to the top edgeMIDDLE- watermark centered verticallyBOTTOM- watermark anchored to the bottom edge
Horizontal alignment (HorizontalAlignment):
LEFT- watermark anchored to the left edgeCENTER- watermark centered horizontallyRIGHT- watermark anchored to the right edge
applyWatermark(html) with no additional parameters is equivalent to passing opacity 50, VerticalAlignment.MIDDLE, HorizontalAlignment.CENTER.Pair any vertical value with any horizontal value for precise control. For documents requiring multiple overlapping stamps, such as a logo in the top-right corner and a draft notice centered diagonally, apply each stamp as a separate applyWatermark call. For annotation-based overlays, see the annotations example.
How Do I Apply Advanced Watermarks with TextStamper and ImageStamper?
The applyWatermark method handles most watermarking needs, but the TextStamper and ImageStamper classes offer programmatic control when exact pixel coordinates, page-range targeting, or dynamic text generation is required. Both classes belong to the com.ironsoftware.ironpdf.stamp package.
TextStamper accepts a string value and exposes properties for font, font size, font color, horizontal and vertical alignment, and opacity. It also supports rotation as an integer (degrees). ImageStamper accepts a file path or byte array for the image and exposes the same alignment and opacity controls as TextStamper.
The key advantage of the stamper classes over applyWatermark is the ability to target specific pages. Pass a list of zero-indexed page numbers to the stamp method to apply the watermark only to the pages that need it, for example stamping only the cover page of a report or the final approval page of a contract.
//:path=/static-assets/pdf/content-code-examples/how-to/custom-watermark/text-stamper.java
import java.io.IOException;
import java.nio.file.Paths;
import java.util.Arrays;
import com.ironsoftware.ironpdf.License;
import com.ironsoftware.ironpdf.PdfDocument;
import com.ironsoftware.ironpdf.stamp.HorizontalAlignment;
import com.ironsoftware.ironpdf.stamp.TextStamper;
import com.ironsoftware.ironpdf.stamp.VerticalAlignment;
public class Main {
public static void main(String[] args) throws IOException {
// Set the license key for IronPDF
License.setLicenseKey("IRONPDF-MYLICENSE-KEY-1EF01");
// Load the target PDF document
PdfDocument pdf = PdfDocument.fromFile(Paths.get("sample.pdf"));
// Configure a TextStamper with custom font, rotation, and opacity
TextStamper stamper = new TextStamper();
stamper.setText("DRAFT");
stamper.setFontSize(72);
stamper.setFontColor("gray");
stamper.setOpacity(40);
stamper.setRotation(45);
stamper.setVerticalAlignment(VerticalAlignment.MIDDLE);
stamper.setHorizontalAlignment(HorizontalAlignment.CENTER);
// Apply the stamp only to pages 0 and 1 (zero-indexed)
pdf.stamp(stamper, Arrays.asList(0, 1));
// Save the stamped PDF
pdf.saveAs("text_stamped.pdf");
}
}
//:path=/static-assets/pdf/content-code-examples/how-to/custom-watermark/text-stamper.java
import java.io.IOException;
import java.nio.file.Paths;
import java.util.Arrays;
import com.ironsoftware.ironpdf.License;
import com.ironsoftware.ironpdf.PdfDocument;
import com.ironsoftware.ironpdf.stamp.HorizontalAlignment;
import com.ironsoftware.ironpdf.stamp.TextStamper;
import com.ironsoftware.ironpdf.stamp.VerticalAlignment;
public class Main {
public static void main(String[] args) throws IOException {
// Set the license key for IronPDF
License.setLicenseKey("IRONPDF-MYLICENSE-KEY-1EF01");
// Load the target PDF document
PdfDocument pdf = PdfDocument.fromFile(Paths.get("sample.pdf"));
// Configure a TextStamper with custom font, rotation, and opacity
TextStamper stamper = new TextStamper();
stamper.setText("DRAFT");
stamper.setFontSize(72);
stamper.setFontColor("gray");
stamper.setOpacity(40);
stamper.setRotation(45);
stamper.setVerticalAlignment(VerticalAlignment.MIDDLE);
stamper.setHorizontalAlignment(HorizontalAlignment.CENTER);
// Apply the stamp only to pages 0 and 1 (zero-indexed)
pdf.stamp(stamper, Arrays.asList(0, 1));
// Save the stamped PDF
pdf.saveAs("text_stamped.pdf");
}
}
The stamp method accepts a List<Integer> of zero-indexed page numbers, giving precise control over which pages receive the watermark. When no page list is provided, the stamp applies to all pages. This makes TextStamper the right choice whenever your application generates watermarks dynamically, such as embedding a unique transaction ID, username, or timestamp on each generated PDF.
TextStamper and ImageStamper classes share a common Stamper base class. Use the stamper approach whenever your application generates watermarks dynamically, for instance embedding a unique transaction ID or username on each generated PDF.For batch processing, such as stamping hundreds of PDFs with unique customer-specific watermarks, load and stamp each PdfDocument in a loop, then call saveAs before the next iteration. IronPDF processes each document independently, so memory usage stays bounded. The Java PDF stamp guide covers ImageStamper and additional stamping options in detail, and the IronPDF Java documentation provides the complete API reference.
How Does TextStamper Differ from applyWatermark?
The applyWatermark method is optimized for quick, consistent multi-page stamps from HTML strings. TextStamper and ImageStamper address scenarios where applyWatermark falls short: targeting a subset of pages, applying multiple distinct stamps with different configurations, or building watermark parameters programmatically from a database or user input. Both approaches produce vector-quality output embedded directly in the PDF content stream, so the watermarks survive re-saving, printing, and PDF readers that do not honor optional content layers.
Developers working with the Apache PDFBox library for watermarking will find IronPDF's approach significantly simpler. PDFBox requires manually constructing content streams and managing resources, whereas applyWatermark accepts a plain HTML string. The iText watermarking guide on Baeldung illustrates a comparable task with iText, which involves creating PdfStampAnnotation objects and adding them through a PdfCanvas pipeline. IronPDF reduces that to a single method call.
PdfDocument.extractAllText() and check for the expected watermark string, or use the Stack Overflow community discussion on Java PDF manipulation for common troubleshooting patterns.What Are the Next Steps for PDF Watermarking in Java?
This guide covered four approaches to watermarking PDFs with IronPDF for Java: simple text watermarks via applyWatermark, image watermarks using HTML <img> tags, opacity and alignment control through method parameters, and programmatic stamping with TextStamper and ImageStamper for advanced use cases.
Start your free trial to test watermarking in your Java application. The trial includes full access to all stamping and watermarking features with no time limit on evaluation. When you are ready to deploy, view licensing options to find the tier that fits your usage.
Ready to see what else you can do? Check out the full tutorial page here: IronPDF for Java How-To Guides
Frequently Asked Questions
How do I add a text watermark to a PDF in Java?
Load your PDF with PdfDocument.fromFile(), then call pdf.applyWatermark() with an HTML string. IronPDF renders any valid HTML and CSS, so you can set color, font size, and opacity directly on the element.
Can I use images as watermarks in Java?
Yes. Pass an <img> tag inside your HTML string to applyWatermark(). PNG files with transparent backgrounds produce the clearest results. You can also use the ImageStamper class for page-range targeting.
How do I control watermark opacity?
Pass an integer from 0 (fully transparent) to 100 (fully opaque) as the second argument to applyWatermark(). Values between 20 and 40 work well for most documents without obscuring body text.
Can I rotate a watermark diagonally?
Yes. Add a CSS transform: rotate(-45deg) style to your HTML element before passing it to applyWatermark(). IronPDF applies all standard CSS3 transforms during rendering.
What is the difference between applyWatermark and TextStamper?
applyWatermark() is the fastest approach for applying the same HTML-based stamp to every page. TextStamper offers programmatic control over font, rotation, and a page list for targeting specific pages only.
How do I position a watermark at a specific location?
Pass VerticalAlignment and HorizontalAlignment enum values as the third and fourth arguments to applyWatermark(). Available positions include TOP, MIDDLE, BOTTOM combined with LEFT, CENTER, RIGHT.
Can I apply different watermarks to different pages?
Yes. Use TextStamper or ImageStamper and pass a list of zero-indexed page numbers to the stamp() method to target only the pages that require a specific watermark.
Can I combine text and image watermarks in the same PDF?
Yes. Call applyWatermark() multiple times or make multiple stamp() calls before saving. Each call adds a new layer to the PDF content stream independently.


