@czhanp/universal-watermark-skill
v0.1.3
Published
A multi-format watermarking Skill and CLI for documents, PDFs, spreadsheets, slides, images, and GIFs.
Maintainers
Readme
universal-watermark
A code-first multi-format watermarking Agent Skill and Python CLI for Word, PDF, PowerPoint, Excel, images, and GIFs.
universal-watermark automatically detects file types, chooses the correct processor, applies visible text watermarks, and writes new output files without overwriting the original files.
Why this project?
Most watermark tools focus on one format, usually PDF or images. This project is built for mixed real-world files:
- Word, PDF, PowerPoint, Excel, images, and GIFs;
- automatic file type detection;
- repeated, diagonal, semi-transparent text watermarks;
- batch processing from one command;
- safe output rules that keep the original file unchanged;
- reusable Agent Skill installation through npm.
Preview
The following preview shows watermark effects on PDF, Word, image, Excel, and PowerPoint files.
Quick Start
Install Python dependencies:
pip install pillow lxml python-docx pymupdf python-pptxAdd a watermark to one file:
python scripts/universal_watermark.py input.pdf --text "CONFIDENTIAL"Batch process multiple files:
python scripts/universal_watermark.py a.docx b.pdf c.pptx table.xlsx image.jpg --output-dir watermarked --text "INTERNAL USE"Use a Chinese font when needed:
python scripts/universal_watermark.py input.pdf --text "试用水印" --font-path "C:\Windows\Fonts\msyh.ttc"Install as an Agent Skill
This repository can be installed as a local Skill for Codex, Claude Code, or other agent workflows.
npm install -g @czhanp/universal-watermark-skill
universal-watermark-skill install --allDefault installation targets:
~/.codex/skills/universal-watermark
~/.claude/skills/universal-watermark
~/.agents/skills/universal-watermarkInstall for one target only:
universal-watermark-skill install --target codex
universal-watermark-skill install --target claude
universal-watermark-skill install --target agentsRun the installer once without keeping the npm package globally:
npm exec --yes --package=@czhanp/universal-watermark-skill -- universal-watermark-skill install --allThe npm package is used to distribute the Skill files. The actual watermarking logic is implemented in Python, so Python dependencies still need to be installed separately.
Supported Formats
| Category | Formats |
|---|---|
| Word | .docx, .doc, .rtf, .odt |
| PDF | .pdf |
| PowerPoint | .pptx, .ppt |
| Excel | .xlsx, .xlsm, .xltx, .xltm, .xls, .ods, .csv |
| Images | .png, .jpg, .jpeg, .webp, .bmp, .tif, .tiff |
| Animated images | .gif |
Legacy Office and non-OOXML formats such as .doc, .ppt, .xls, .rtf, .odt, .ods, and .csv may require LibreOffice conversion before watermarking.
Common CLI Examples
Word / DOCX
python scripts/universal_watermark.py report.docx --text "Trial Watermark" --angle 45 --opacity 0.18python scripts/universal_watermark.py paper.pdf --text "Internal Use" --opacity 0.15PowerPoint
python scripts/universal_watermark.py slides.pptx --text "Draft" --angle -45Excel
Use worksheet background watermark:
python scripts/universal_watermark.py table.xlsx --text "Trial Watermark" --excel-mode backgroundUse transparent overlay watermark for printing or PDF export:
python scripts/universal_watermark.py table.xlsx --text "Trial Watermark" --excel-mode overlay --opacity 0.12Use both modes:
python scripts/universal_watermark.py table.xlsx --text "Trial Watermark" --excel-mode both --opacity 0.10Images
python scripts/universal_watermark.py image.jpg --text "Trial Watermark"GIF
python scripts/universal_watermark.py animation.gif --text "Trial Watermark"Legacy Office Files
Convert to editable modern Office format before watermarking:
python scripts/universal_watermark.py old.doc --legacy-target editable
python scripts/universal_watermark.py old.ppt --legacy-target editable
python scripts/universal_watermark.py old.xls --legacy-target editableConvert to PDF before watermarking:
python scripts/universal_watermark.py old.doc --legacy-target pdfWatermark Layouts
checkerboard
checkerboard is the recommended visual layout. It alternates text slots and empty slots to avoid overly dense repeated watermarks.
python scripts/universal_watermark.py input.pdf \
--text "Trial Watermark" \
--layout checkerboard \
--spacing-x-font-multiplier 2.0 \
--spacing-y-font-multiplier 3.0 \
--empty-slot-multiplier 1.0staggered
staggered is the traditional tiled watermark layout where every other row is shifted horizontally.
python scripts/universal_watermark.py input.pdf --text "Trial Watermark" --layout staggeredCommon Options
| Option | Description | Example |
|---|---|---|
| --text | Watermark text | --text "Trial Watermark" |
| --angle | Rotation angle | --angle 45 |
| --opacity | Watermark opacity, from 0 to 1 | --opacity 0.18 |
| --color | RGB color or hex color | --color "#808080" |
| --font-path | Path to a font file | --font-path "C:\Windows\Fonts\msyh.ttc" |
| --layout | Watermark layout | --layout checkerboard |
| --output-dir | Output directory | --output-dir watermarked |
| --suffix | Output filename suffix | --suffix "_watermarked" |
| --legacy-target | Legacy file conversion target | --legacy-target editable |
| --excel-mode | Excel watermark mode | --excel-mode background |
Check the current CLI help before using advanced options:
python scripts/universal_watermark.py --helpExcel Watermark Modes
Excel does not provide a native watermark layer like Word. This project provides practical alternatives:
| Mode | Description | Best for |
|---|---|---|
| background | Adds a worksheet background image | Viewing and editing |
| overlay | Adds transparent image overlays | Printing and PDF export |
| both | Uses both background and overlay | Strongest visible effect |
Recommended default:
--excel-mode backgroundFor printing or exporting to PDF:
--excel-mode overlay --opacity 0.12Output Rules
The tool never overwrites the original file by default.
report.docx -> report_watermarked.docx
paper.pdf -> paper_watermarked.pdf
slides.pptx -> slides_watermarked.pptx
table.xlsx -> table_watermarked.xlsx
image.jpg -> image_watermarked.jpgIf the output file already exists, a numeric suffix is added automatically:
report_watermarked.docx
report_watermarked_1.docx
report_watermarked_2.docxProject Structure
universal-watermark/
SKILL.md
README.md
README_zh-CN.md
LICENSE
package.json
bin/
install.js
scripts/
universal_watermark.py
watermark/
cli.py
detector.py
dispatcher.py
word.py
pdf.py
ppt.py
excel.py
image.py
gif.py
converters.py
common.py
options.py
constants.py
svg.py
example/Notes and Limitations
- Legacy Office files such as
.doc,.ppt, and.xlsrequire conversion before watermarking. - LibreOffice conversion may cause slight layout differences.
- PDF watermarking overlays watermark content onto pages, so low opacity is recommended.
- Excel
backgroundmode usually does not appear in printing. - Excel
overlaymode is more suitable for printing but may affect cell selection. - GIF output may have slight quality changes because of palette limitations.
- Very large images or multi-page TIFF files may require more memory.
- Encrypted PDFs require appropriate permission before processing.
Development
Check Python syntax:
python -m compileall scriptsShow CLI help:
python scripts/universal_watermark.py --helpSuggested maintenance areas:
| Module | Purpose |
|---|---|
| scripts/watermark/word.py | Word / DOCX watermarking |
| scripts/watermark/pdf.py | PDF watermarking |
| scripts/watermark/ppt.py | PowerPoint / PPTX watermarking |
| scripts/watermark/excel.py | Excel / XLSX / XLSM watermarking |
| scripts/watermark/image.py | Static image watermarking |
| scripts/watermark/gif.py | Animated GIF watermarking |
| scripts/watermark/common.py | Shared watermark layer, font, and OOXML utilities |
| scripts/watermark/options.py | Watermark option definitions |
License
MIT License.
