Skip to main content

banner

PyPI PyPI - Python Version

Product Page | Docs | Demos | API Reference | Blog | Free Support | Temporary License

GroupDocs.Watermark for Python via .NET is a document-watermarking API for adding, searching, and removing text and image watermarks. Stamp configurable text or image watermarks — with control over position, size, opacity, rotation, alignment, and tiling — then save the result back to the original format; search for and remove existing watermarks (including ones added by other tools) across PDF, Word, Excel, PowerPoint, Visio, email, and image formats through one unified API, with no MS Office or other external software required.

Get Started

pip install groupdocs-watermark-net
from groupdocs.watermark import Watermarker
from groupdocs.watermark.watermarks import TextWatermark, Font

with Watermarker("document.pdf") as watermarker:
    watermark = TextWatermark("CONFIDENTIAL", Font("Arial", 36.0))
    watermark.opacity = 0.5
    watermarker.add(watermark)
    watermarker.save("watermarked.pdf")

How It Works

The package is a self-contained Python wheel that bundles the embedded .NET runtime and the native libraries it ships (SkiaSharp, Aspose.Drawing) to load, watermark, render, and save documents. On Windows nothing else is needed; on Linux and macOS a few system packages are - see System Requirements. The wheel works across Python 3.5 - 3.14 on 64-bit Windows, Linux, and macOS (Intel + Apple Silicon).

Features

  • Text watermarks — configurable font, foreground/background color, opacity, rotation, and alignment.
  • Image watermarks — from a file or an in-memory stream, with scaling, opacity, and positioning.
  • Positioning & sizing — absolute coordinates, horizontal/vertical alignment, margins, scale-to-parent sizing, and rotation.
  • Tiling — repeat a watermark across the page with configurable tile lines and spacing.
  • Search — find existing watermarks by text, image, color, size, or rotation, combined with AND/OR/NOT criteria.
  • Remove — delete found watermarks individually or in batches and save the cleaned document.
  • Document introspection — read format, page count, and per-page dimensions before processing.
  • Previews — render pages to PNG/JPEG/BMP images via a page-stream callback.
  • Cross-Platform - Windows x64, Linux x64, macOS x64/ARM64.

Common Tasks

  • Stamp a "CONFIDENTIAL" text watermark across every page of a PDF and save it back
  • Add a semi-transparent logo image watermark to a Word or PowerPoint document
  • Tile a watermark diagonally across a page
  • Search a document for an existing watermark by its text and remove it
  • Read a document's format and page count before processing
  • Render watermarked pages to images for a preview UI

Supported File Formats

For a complete list, see supported formats.

Category Formats
Word Processing DOC, DOCX, DOCM, DOT, DOTX, RTF, ODT
Spreadsheets XLS, XLSX, XLSM, XLSB
Presentations PPT, PPTX, PPTM, PPS, PPSX
Fixed-Layout PDF
Diagrams VSD, VSDX, VSS, VDX
Email MSG, EML, EMLX
Images BMP, JPG, JPEG, PNG, GIF, TIFF, WEBP

Examples

Add a text watermark

from groupdocs.watermark import Watermarker
from groupdocs.watermark.watermarks import TextWatermark, Font, Color

with Watermarker("document.pdf") as watermarker:
    watermark = TextWatermark("CONFIDENTIAL", Font("Arial", 48))
    watermark.foreground_color = Color.red
    watermark.opacity = 0.5
    watermark.rotate_angle = -45
    watermarker.add(watermark)
    watermarker.save("watermarked.pdf")

Add an image watermark

from groupdocs.watermark import Watermarker
from groupdocs.watermark.watermarks import ImageWatermark, SizingType

with Watermarker("document.docx") as watermarker:
    watermark = ImageWatermark("logo.png")
    watermark.sizing_type = SizingType.SCALE_TO_PARENT_DIMENSIONS
    watermark.scale_factor = 0.5
    watermark.opacity = 0.7
    watermarker.add(watermark)
    watermarker.save("watermarked.docx")

Tile a watermark across the page

from groupdocs.watermark import Watermarker
from groupdocs.watermark.watermarks import TextWatermark, Font, TileOptions, TileType

with Watermarker("document.pdf") as watermarker:
    watermark = TextWatermark("DRAFT", Font("Arial", 19))
    tile = TileOptions()
    tile.tile_type = TileType.STRAIGHT           # repeat across the page
    watermark.tile_options = tile
    watermark.opacity = 0.3
    watermarker.add(watermark)
    watermarker.save("tiled.pdf")

Search for and remove a watermark

from groupdocs.watermark import Watermarker
from groupdocs.watermark.search.search_criteria import TextSearchCriteria

with Watermarker("watermarked.pdf") as watermarker:
    criteria = TextSearchCriteria("CONFIDENTIAL")     # also: ImageSearchCriteria(...)
    possible = watermarker.search(criteria)
    print("found:", len(possible))
    for wm in possible:
        print(wm.text, wm.x, wm.y)
    watermarker.remove(possible)                       # remove the whole collection
    watermarker.save("clean.pdf")

Read document info

from groupdocs.watermark import Watermarker

with Watermarker("document.pdf") as watermarker:
    info = watermarker.get_document_info()
    print("format:", info.file_type)
    print("pages:", info.page_count)

Render page previews

from groupdocs.watermark import Watermarker
from groupdocs.watermark.options import PreviewOptions, PreviewFormats

def create_page_stream(page_number):
    return open("page-%d.png" % page_number, "wb")

def release_page_stream(page_number, stream):
    stream.close()                          # the object create_page_stream returned

with Watermarker("document.pdf") as watermarker:
    options = PreviewOptions(create_page_stream, release_page_stream)
    options.preview_format = PreviewFormats.PNG
    options.page_numbers = [1, 2]
    watermarker.generate_preview(options)

create_page_stream may also return an io.BytesIO; it is filled by the time release_page_stream gets it.

Watermark from / to a binary stream

import io
from groupdocs.watermark import Watermarker
from groupdocs.watermark.watermarks import TextWatermark, Font

with open("document.pdf", "rb") as src:
    with Watermarker(src) as watermarker:
        watermarker.add(TextWatermark("CONFIDENTIAL", Font("Arial", 36)))
        buffer = io.BytesIO()
        watermarker.save(buffer)          # BytesIO is updated after save
        data = buffer.getvalue()

AI Agent & LLM Friendly

This package is designed for seamless integration with AI agents, LLMs, and automated code generation tools.

  • AGENTS.md in the package — AI coding assistants (Claude Code, Cursor, GitHub Copilot) auto-discover the API surface, usage patterns, and troubleshooting tips from the installed package
  • MCP server — connect your AI tool to GroupDocs documentation for on-demand API lookups:
    { "mcpServers": { "groupdocs-docs": { "url": "https://docs.groupdocs.com/mcp" } } }
    
  • Machine-readable docs — full documentation available as plain text for RAG and LLM context:
    • Single file: https://docs.groupdocs.com/watermark/python-net/llms-full.txt
    • Per page: append .md to any docs URL

Evaluation Mode

The API works without a license in evaluation mode. Every feature runs - adding several watermarks, search, and removal included - and there is no cap on the number of documents, but each saved document carries an evaluation mark:

  • PDF and image files: the line "Evaluation only. Created with GroupDocs.Watermark."
  • Word, PowerPoint, and Visio files: the line "Created with evaluation version of GroupDocs.Watermark".
  • Excel files: an extra "Evaluation Warning" worksheet.

To remove the mark, apply a license or request a temporary license:

from groupdocs.watermark import License
License().set_license("path/to/license.lic")

Or set the environment variable (auto-applied at import):

export GROUPDOCS_LIC_PATH="path/to/license.lic"

Troubleshooting

Issue Platform Fix
"Evaluation only" / "Created with evaluation version" line, or an "Evaluation Warning" sheet, in the output All No license is applied: set GROUPDOCS_LIC_PATH or call License().set_license(path)
The type initializer for 'Gdip' threw an exception / DllNotFoundException: libgdiplus when adding a watermark Linux/macOS Install libgdiplus: apt-get install libgdiplus / brew install mono-libgdiplus. Only text watermarks on Word, Excel, PowerPoint, Visio, and image files, text watermarks on PDF that set sizing_type, and image watermarks, removal, and previews on PowerPoint need it; the rest of PDF works without it
FontNotFoundException when adding a text watermark to a PDF Linux Install the font the watermark names - for Arial and the other Microsoft fonts: apt-get install ttf-mscorefonts-installer (Debian: enable contrib), then fc-cache -f. Liberation fonts are not substituted
Not implemented. from generate_preview on a PowerPoint file Linux/macOS PowerPoint previews need a GDI+ feature libgdiplus lacks; generate them on Windows. Previews of the other formats work
The process aborts on first use with Couldn't find a valid ICU package Linux Install ICU: apt-get install libicu-dev; do NOT set DOTNET_SYSTEM_GLOBALIZATION_INVARIANT
is not a supported wheel on this platform, or No matching distribution found Linux/macOS The OS is older than the wheel needs (glibc 2.27, macOS 12), or pip is older than 20.3: python -m pip install --upgrade pip. On an Intel Mac, a Python built against an old SDK reports macOS 10.16 - use pip 24.1+ or SYSTEM_VERSION_COMPAT=0 pip install groupdocs-watermark-net

System Requirements

  • Python 3.5 - 3.14, pip 20.3 or newer
  • Windows x64, Linux x64, macOS x64/ARM64 - 64-bit Python only; there is no 32-bit Windows wheel
  • Linux: glibc 2.27 or newer (e.g. Ubuntu 18.04+, Debian 10+, RHEL 8+), plus ICU, fontconfig, libgdiplus and the Microsoft core fonts: apt-get install libicu-dev libfontconfig1 libgdiplus ttf-mscorefonts-installer (on Debian, enable the contrib component first). libgdiplus is needed for text watermarks on Word, Excel, PowerPoint, Visio, and image files, for text watermarks on PDF files that set sizing_type, and for image watermarks, removal, and previews on PowerPoint files; the core fonts for text watermarks on PDF files, which look their font up by name.
  • macOS 12 or newer, Intel or Apple Silicon: brew install mono-libgdiplus for the same features.

Upgrading from 26.6

  • release_page_stream(page_number, stream) now gets the stream create_page_stream returned; 26.6 passed None. A one-argument release_page_stream(page_number) still works.
  • Previews written through a release callback are complete (26.6 could leave a spreadsheet page truncated), and io.BytesIO pages are filled (26.6 left them empty).
  • WatermarkerSettings.logger takes a Python object with trace, warning, and error methods, or a function fn(level, message, exception).
  • Assigning an attribute a class does not have raises AttributeError with a suggestion (watermark.opactiy = 0.5 -> "Did you mean: 'opacity'?"); 26.6 stored it on the Python object and changed nothing.
  • Python 3.5, 3.6, and 3.7 work; 26.6 could not be imported on 3.5 and 3.6 and failed on first use on 3.7.
  • Evaluation mode allows several watermarks per document, search, and removal (engine 26.9).
  • The wheels state the OS they need (manylinux_2_27, macosx_12_0), so installing needs pip 20.3 or newer.

The release notes have the full list.

More Resources

Also available for other platforms: .NET | Java | Node.js


Product Page | Docs | Demos | API Reference | Blog | Free Support | Temporary License

Metadata

Release files for groupdocs-watermark-net 26.10.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for groupdocs-watermark-net 26.10.0
File
groupdocs_watermark_net-26.10.0-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details
groupdocs_watermark_net-26.10.0-py3-none-manylinux_2_27_x86_64.whl Python 3 none Linux glibc 2.27+ x86-64 Details
groupdocs_watermark_net-26.10.0-py3-none-macosx_12_0_x86_64.whl Python 3 none macOS 12.0+ x86-64 Details
groupdocs_watermark_net-26.10.0-py3-none-macosx_12_0_arm64.whl Python 3 none macOS 12.0+ ARM64 Details

Total release size: 550.0 MB

Release files / groupdocs_watermark_net-26.10.0-py3-none-win_amd64.whl

Download URL groupdocs_watermark_net-26.10.0-py3-none-win_amd64.whl
Size 137.5 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
831b596d14b0feda5a9f7d28b2f4db78d3beb259243afb385285393f049fdb20
BLAKE2b-256 checksum
How to use checksums
1769f6c117684b35e4186f7f5ab63b1e7a711f3846aafce92f9560bc68e420f2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / groupdocs_watermark_net-26.10.0-py3-none-manylinux_2_27_x86_64.whl

Download URL groupdocs_watermark_net-26.10.0-py3-none-manylinux_2_27_x86_64.whl
Size 136.9 MB
Tags Linux glibc 2.27+ x86-64 Python 3
SHA-256 checksum
How to use checksums
a7c4cb25ac7d92ef4bbc1e43b165d663f31817a7c3c64dee6fb306ad7ab4bf8f
BLAKE2b-256 checksum
How to use checksums
14052d1577b56393ac631d8f489adfb739a63a695c6ca120d56929c39512d744
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / groupdocs_watermark_net-26.10.0-py3-none-macosx_12_0_x86_64.whl

Download URL groupdocs_watermark_net-26.10.0-py3-none-macosx_12_0_x86_64.whl
Size 138.9 MB
Tags Python 3 macOS 12.0+ x86-64
SHA-256 checksum
How to use checksums
0298efae35dafafaf02a76a0d3de262ade04db4ebcca36eeaebed19014519ac7
BLAKE2b-256 checksum
How to use checksums
bc8e0865d99807595dfc496598aef81d982d9c7f8ef8801f74a2e48ed8559c90
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / groupdocs_watermark_net-26.10.0-py3-none-macosx_12_0_arm64.whl

Download URL groupdocs_watermark_net-26.10.0-py3-none-macosx_12_0_arm64.whl
Size 136.7 MB
Tags Python 3 macOS 12.0+ ARM64
SHA-256 checksum
How to use checksums
23eb3139ec065a7be73a14a3da988b81d44a00c40cac83c958ebac59631a06e2
BLAKE2b-256 checksum
How to use checksums
a330550cb01e11286000e4fd8fe7ed526d1926cda0aad363125e5e46bc491410
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release history Release notifications | RSS feed

This release

26.10.0 This release

4 release files

26.6.0

4 release files

25.12

5 release files

25.3

4 release files

24.9.1

3 release files

24.9

2 release files

24.5

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page