How-to guides/Watermarks & Stamps

Apply a stamp or label to each page of a PDF in Rust

Draw text or an image stamp at a fixed position on every page, with configurable opacity, size, and rotation.

rust
use pdfluent::{Document, stamp::{TextStamp, StampPosition}};

fn main() -> pdfluent::Result<()> {
    let mut doc = Document::open("input.pdf")?;

    let stamp = TextStamp::new("CONFIDENTIAL")
        .position(StampPosition::Center)
        .font_size(48.0)
        .opacity(0.25)
        .rotation(45.0)
        .color(pdfluent::color::Color::rgb(0.8, 0.0, 0.0));

    doc.apply_stamp(&stamp)?;
    doc.save("stamped.pdf")?;
    Ok(())
}
Install:cargo add pdfluentDownload SDK →

Step by step

1

Open the document

Stamps are applied to page content streams. Open the file for mutation.

rust
let mut doc = Document::open("input.pdf")?;
2

Build a text stamp

TextStamp::new takes the stamp text. Chain builder methods for position, size, color, rotation, and opacity.

rust
use pdfluent::stamp::{TextStamp, StampPosition};

let stamp = TextStamp::new("DRAFT")
    .position(StampPosition::Center)
    .font_size(72.0)
    .opacity(0.15)
    .rotation(45.0);
3

Apply the stamp to all pages

doc.apply_stamp() iterates all pages and appends the stamp as a graphics operator block in each content stream.

rust
doc.apply_stamp(&stamp)?;
4

Apply a stamp to specific pages only

Use apply_stamp_to_page to target individual pages.

rust
// Stamp only pages 1 and 3 (zero-indexed: 0, 2)
doc.apply_stamp_to_page(&stamp, 0)?;
doc.apply_stamp_to_page(&stamp, 2)?;
5

Apply an image stamp

Load a PNG or JPEG and use ImageStamp to overlay it on each page.

rust
use pdfluent::stamp::{ImageStamp, StampPosition};

let image_data = std::fs::read("stamp_logo.png")?;
let img_stamp = ImageStamp::from_png(&image_data)
    .position(StampPosition::BottomRight)
    .width_pt(120.0)
    .opacity(0.6);

doc.apply_stamp(&img_stamp)?;
doc.save("stamped.pdf")?;

Notes and tips

  • Stamps are written into the content stream as a transparency group with a gs operator. They cannot be trivially removed without reprocessing the stream.
  • For removable stamps, add them as annotation objects instead. Annotation-based stamps can be toggled or deleted without modifying the content stream.
  • Very low opacity (below 0.1) may not be visible in all viewers. Use 0.15-0.25 for a visible but unobtrusive stamp.
  • Rotate the stamp 45 degrees for a diagonal diagonal watermark-style placement. 0 degrees places the text horizontally.

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