Skip to main content

wmk: Python CLI to watermark images (batch watermark, logo watermark, text watermark)

CI PyPI version Python versions License

Python CLI for batch image watermarking with logo or text.

wmk is built for people searching "how to add watermark to image", "add watermark to photo", "put watermark on picture", "add logo to image", "add text watermark to photo", "batch watermark images", "watermark multiple photos at once", and "protect photos with watermark".

20-Second Quickstart: watermark images with a Python CLI

pipx install add-watermark
wmk add
# Expert one-liner: add text watermark to photo
wmk add --input ".\photo.jpg" --text "(c) ACME" --pos br --opacity 40

Install add-watermark for batch watermark, logo watermark, and text watermark

PyPI package name: add-watermark; CLI commands: wmk (primary) and add-watermark (alias).

pipx install add-watermark

If pipx is not on PATH yet:

pipx ensurepath

B) Install (Alternative): pip

python -m pip install add-watermark

C) Install from source (repo clone)

git clone https://github.com/ibrahimm7004/add-watermark.git
cd add-watermark

Install from this repo with pipx:

pipx install .

Install from this repo with pip:

python -m pip install .

D) Uninstall (pipx and pip)

pipx uninstall add-watermark
python -m pip uninstall add-watermark

You can also run the beginner-friendly alias:

add-watermark add

Versioning

This project follows Semantic Versioning (MAJOR.MINOR.PATCH):

  • MAJOR: breaking CLI/API changes
  • MINOR: backward-compatible features
  • PATCH: backward-compatible fixes

Check the installed CLI version:

wmk --version

Before and after: put watermark on picture

Before After
Before watermark example After watermark example

Regenerate both demo images:

python examples/generate_examples.py

Add watermark to photo: wizard and expert one-liners

Beginner wizard:

wmk add

Single image with text watermark:

wmk add --input ".\photo.jpg" --text "(c) ACME Studio" --pos br --opacity 40

Single image with logo watermark:

wmk add --input ".\photo.jpg" --watermark ".\logo.png" --pos tr --opacity 35

Batch watermark folder:

wmk add --input ".\photos" --watermark ".\logo.png" --pos br --opacity 35

Batch watermark folder recursively:

wmk add --input ".\photos" --recursive --text "(c) ACME" --pos br --opacity 35

Glob input:

wmk add --input ".\photos\**\*.png" --watermark ".\logo.png" --opacity 35

Dry run (plan only):

wmk add --input ".\photos" --watermark ".\logo.png" --dry-run

Defaults

wmk add defaults (from current implementation):

  • Default position: br
  • Default opacity: 35 (0 is invisible, 100 is fully visible)
  • Default corner margin: 24px
  • Image watermark default scale: target width is about 20% of base image width, clamped to at least 48px and at most 80% of base width
  • Text watermark default scale: font size is about 5% of image width, clamped to 16..256
  • Text watermark style: white text with black stroke and subtle shadow for readability
  • Single-image default output: <input_stem>_watermarked.<ext> next to input
  • Batch default output (folder input): watermarked/ next to the input folder
  • Batch default output (glob input): ./watermarked/ in current working directory
  • Batch mode preserves relative folder structure for folder input
  • For glob input, paths are preserved only when files are under the current working directory; otherwise output falls back to filenames under ./watermarked/
  • Without --overwrite, existing destination paths are not replaced; a _watermarked suffix is appended to avoid collisions

Windows notes

  • Quote paths that contain spaces:
    • PowerShell/CMD: --input "C:\Users\me\My Photos\photo 01.jpg"
  • Quote globs to keep behavior consistent across shells and avoid shell expansion differences:
    • --input ".\photos\**\*.jpg"
  • PowerShell example:
wmk add --input ".\My Photos\Client A" --recursive --text "(c) ACME" --pos br --opacity 35
  • CMD example:
wmk add --input ".\My Photos\*.jpg" --watermark ".\brand logo.png" --pos tr --opacity 35

Why offline CLI (vs online watermark tools)

If you are searching for "add watermark to image online free", an offline CLI is often better for production workflows:

  • Privacy: images stay on your machine
  • Speed: no upload/download loop
  • Batch scale: watermark hundreds of files in one command
  • Automation: scriptable for product photos, photography delivery, and repeatable pipelines

Supported formats and behavior

  • Input/output formats: jpg, jpeg, png, webp, tiff, bmp, gif
  • GIF behavior: first frame only
  • JPEG output is written as RGB (quality 95)
  • PNG/WEBP preserve alpha when present

Common searches this tool solves

  • how to add watermark to image
  • add watermark to photo
  • put watermark on picture
  • how to watermark a photo
  • add logo to image
  • add text watermark to photo
  • batch watermark images
  • bulk watermark photos
  • watermark multiple photos at once
  • add watermark to 100 photos
  • signature watermark
  • copyright watermark on images

CLI reference

wmk add [OPTIONS]

Options:
  --input, -i      File path, folder path, or glob pattern
  --output, -o     Output file (single mode) or output folder (batch mode)
  --watermark, -w  Watermark image path
  --text, -t       Text watermark content
  --pos            Watermark position: tl|tr|bl|br|c
  --opacity        Opacity 0-100 (0 invisible, 100 fully visible)
  --recursive      Recurse subfolders for folder input
  --overwrite      Overwrite existing outputs
  --dry-run        Print planned outputs without writing files
  --verbose        Show traceback/debug details

Validation rules:

  • Exactly one of --watermark or --text in non-interactive mode
  • If --input is missing, wizard prompts for required fields

Library usage (optional)

CLI is the primary interface. If you need direct Python usage:

from pathlib import Path

from watermarker.engine import process_single

process_single(
    input_path=Path("photo.jpg"),
    output_path=Path("photo_watermarked.jpg"),
    text="(c) ACME",
    position="br",
    opacity=35,
    overwrite=True,
)

Open source trust signals

FAQ and troubleshooting

wmk command is not found on Windows

  • For pipx installs, run pipx ensurepath and restart terminal.
  • For pip installs, ensure your Python Scripts directory is on PATH.

Why does GIF output look static?

  • v1 processes only the first GIF frame.

Why can text look slightly different across machines?

  • The tool tries common system fonts first and falls back to Pillow default when needed.

Development

python -m pip install -e .[dev]
ruff check .
ruff format --check .
pytest

Metadata

Release files for add-watermark 0.1.1

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

Source distribution (sdist)

Source distribution for add-watermark 0.1.1
File Size Uploaded
add_watermark-0.1.1.tar.gz 13.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for add-watermark 0.1.1
File Interpreter ABI Platform
add_watermark-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 26.9 kB

Release files / add_watermark-0.1.1.tar.gz

Download URL add_watermark-0.1.1.tar.gz
Size 13.2 kB
Tags Source
SHA-256 checksum
How to use checksums
ff7c4c0f3b77d6fb3c5124b4973b2ae9430e0bb8d17347040783a3fa518f052d
BLAKE2b-256 checksum
How to use checksums
62f2191a7443f02428688e86f46ed46df861467f38f73b2f358b0cbc23ecc2c7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.7

Release files / add_watermark-0.1.1-py3-none-any.whl

Download URL add_watermark-0.1.1-py3-none-any.whl
Size 13.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4da72565d0390b91129e4ae4d62c6b315369dfdc213419a500cdd787451fc1a3
BLAKE2b-256 checksum
How to use checksums
acca4b2888d9b0742209d56ad85d03795e56c1978402727dd219ced756bf377e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.7

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

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