How-to guides/Watermarks & Stamps

Add a text watermark to a PDF in Rust

Stamp each page with a diagonal text watermark. Control font, size, colour, opacity, rotation, and position.

rust
use pdfluent::{PdfDocument, TextWatermark, WatermarkPosition};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut doc = PdfDocument::open("document.pdf")?;

    let watermark = TextWatermark::new("CONFIDENTIAL")
        .font_size(60.0)
        .opacity(0.15)
        .rotation(45.0)
        .position(WatermarkPosition::Center);

    doc.add_text_watermark(&watermark)?;
    doc.save("document_watermarked.pdf")?;
    Ok(())
}
Install:cargo add pdfluentDownload SDK →

Step by step

1

Open the PDF

Open the document with a mutable binding.

rust
use pdfluent::PdfDocument;

let mut doc = PdfDocument::open("contract.pdf")?;
2

Build a TextWatermark

Create a TextWatermark with the text you want to stamp. Use the builder methods to set style properties.

rust
use pdfluent::TextWatermark;

let watermark = TextWatermark::new("DRAFT")
    .font_size(72.0)
    .opacity(0.12)          // 12% opacity
    .rotation(45.0)         // degrees counter-clockwise
    .color([0.6, 0.0, 0.0]); // dark red, sRGB
3

Set the position

WatermarkPosition::Center places the text at the page centre. Other options include TopLeft, TopRight, BottomLeft, BottomRight, and Custom(x, y).

rust
use pdfluent::WatermarkPosition;

let watermark = watermark.position(WatermarkPosition::Center);
4

Apply to all pages or specific pages

add_text_watermark() stamps every page. Use add_text_watermark_on_pages() to target a subset.

rust
// All pages
doc.add_text_watermark(&watermark)?;

// Specific pages (1-indexed)
doc.add_text_watermark_on_pages(&watermark, &[1, 2, 3])?;
5

Save the result

Save the watermarked document to disk.

rust
doc.save("contract_draft.pdf")?;

Notes and tips

  • Opacity of 0.1 to 0.2 is typical for background watermarks. Higher values produce more prominent stamps.
  • The watermark is drawn as a content stream beneath the page text so it does not obscure the document content.
  • To place the watermark on top of the content instead, use watermark.layer(WatermarkLayer::Foreground).
  • PDFluent uses the Helvetica built-in font by default. Specify a custom font path with .font_path("path/to/font.ttf").

Why PDFluent for this

Pure Rust

No JVM, no runtime, no DLL dependencies. Ships as a single native binary or WASM module.

Memory safe

Rust's ownership model prevents buffer overflows and use-after-free. No segfaults in PDF parsing.

Runs anywhere

Same code runs server-side, in Docker, on AWS Lambda, on Cloudflare Workers, or in the browser via WASM.

Frequently asked questions