Skip to main content

Invisible & visible watermarking SDK for AI-generated images and video

Project description

clawID

Invisible & visible watermarking SDK for AI-generated images and video.

PyPI Python CI License: MIT

A research project by hawky.ai — the AI content provenance platform.

clawID embeds a UUID-based watermark into images and video frames — invisible to the human eye but detectable by the SDK. Inspired by Google SynthID. Built for AI-generated asset provenance tracking.

Links: PyPI · GitHub · Hugging Face Space · hawky.ai


Features

  • Invisible watermarking via DWT-QIM (Discrete Wavelet Transform + Quantization Index Modulation)
  • Resize-robust mode (algorithm='fm') — survives ±35% resize, JPEG compression, and minor edits
  • Visible watermarking — overlay text/logo with configurable opacity and position
  • Video support — watermark every Nth frame; detect from any single watermarked frame
  • REST API — FastAPI server with /embed and /detect endpoints
  • Storage backends — SQLite, PostgreSQL, MongoDB, Redis
  • CLIclawid embed, clawid detect, clawid embed-video, clawid detect-video

Installation

# Core (images only)
pip install clawid

# With video support
pip install "clawid[video]"

# With REST API
pip install "clawid[api]"

# Everything
pip install "clawid[all]"

Quick Start

Images

from clawid import embed, detect

# Embed invisible watermark
meta = embed(
    source='photo.jpg',
    output_path='photo_wm.png',
    metadata={'uid': 'creator123', 'platform': 'hawky.ai'},
)
print(meta['clawid'])  # e.g. "3f2a1b4c-..."

# Detect
result = detect('photo_wm.png')
print(result['uid'])       # creator123
print(result['platform'])  # hawky.ai

Resize-robust mode

meta = embed(
    source='photo.jpg',
    output_path='photo_wm.png',
    metadata={'uid': 'creator123'},
    algorithm='fm',   # survives ±35% resize
)

Video

from clawid import embed_video, detect_video

meta = embed_video(
    'input.mp4',
    'output_wm.mp4',
    metadata={'uid': 'creator123', 'platform': 'hawky.ai'},
    frame_stride=5,   # watermark every 5th frame
)

result = detect_video('output_wm.mp4')
print(result['uid'])  # creator123

Visible watermark

meta = embed(
    source='photo.jpg',
    output_path='photo_wm.png',
    metadata={'uid': 'creator123'},
    mode='visible',     # or 'both' for invisible + visible
    opacity=0.6,
    position='bottom-right',
)

CLI

# Embed
clawid embed -i photo.jpg -o photo_wm.png --uid creator123 --platform hawky.ai

# Embed (resize-robust)
clawid embed -i photo.jpg -o photo_wm.png --uid creator123 --algorithm fm

# Detect
clawid detect -i photo_wm.png

# Video
clawid embed-video -i input.mp4 -o output_wm.mp4 --uid creator123
clawid detect-video -i output_wm.mp4

# Save to SQLite store on embed, enrich on detect
clawid embed -i photo.jpg -o wm.png --uid creator123 --store sqlite:///clawid.db
clawid detect -i wm.png --store sqlite:///clawid.db

REST API

pip install "clawid[api]"
clawid serve --store sqlite:///clawid.db --port 8000

Endpoints:

Method Path Description
POST /embed Upload image, get back watermarked image + metadata
POST /detect Upload image, get back detected metadata
GET /docs Interactive Swagger UI
# Embed via API
curl -X POST http://localhost:8000/embed \
  -F "file=@photo.jpg" \
  -F "uid=creator123" \
  -F "platform=hawky.ai" \
  --output photo_wm.png

# Detect via API
curl -X POST http://localhost:8000/detect \
  -F "file=@photo_wm.png"

Storage Backends

from clawid.storage import from_uri

# SQLite (local)
with from_uri('sqlite:///clawid.db') as store:
    store.save(meta['clawid'], meta)
    record = store.get(meta['clawid'])

# PostgreSQL
with from_uri('postgresql://user:pass@localhost/mydb') as store:
    store.save(meta['clawid'], meta)

# MongoDB
with from_uri('mongodb://localhost:27017/mydb') as store:
    store.save(meta['clawid'], meta)

# Redis
with from_uri('redis://localhost:6379/0') as store:
    store.save(meta['clawid'], meta)

How It Works

Invisible watermark (DWT-QIM)

The payload (UUID + metadata, CBOR-encoded + CRC-checked) is serialised to bits, then each bit is embedded by quantizing a coefficient in the Haar wavelet LL2 sub-band. Each LL2 coefficient represents a 4×4 pixel block, so a change of delta/16 ≈ 2+ pixels per block — above the uint8 quantization step — making the watermark survive JPEG compression and format round-trips.

Mode Delta PSNR Survives
qim (default) 32 ~51 dB PNG/JPEG q≥75, minor edits
fm (resize-robust) 192 ~36 dB ±35% resize, PNG/JPEG q≥75

Video watermarking

Each video is processed frame by frame. Every Nth frame (frame_stride, default 5) receives the same DWT-QIM watermark with the same clawid UUID. Detection samples up to 10 frames and uses majority vote — detection succeeds as long as at least one watermarked frame survives.


Docker

docker compose up
# API available at http://localhost:8000

Development

git clone https://github.com/Hawky-ai/clawID
cd clawid
pip install -e ".[dev,api,video]"
pytest

Links

PyPI https://pypi.org/project/clawid/
GitHub https://github.com/Hawky-ai/clawID
Hugging Face https://huggingface.co/spaces/Hawky-ai/clawID
hawky.ai https://hawky.ai

License

MIT — Copyright © 2024 hawky.ai

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

clawid-0.2.4.tar.gz (41.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

clawid-0.2.4-py3-none-any.whl (37.3 kB view details)

Uploaded Python 3

File details

Details for the file clawid-0.2.4.tar.gz.

File metadata

  • Download URL: clawid-0.2.4.tar.gz
  • Upload date:
  • Size: 41.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.2

File hashes

Hashes for clawid-0.2.4.tar.gz
Algorithm Hash digest
SHA256 0f3d2e6379426b864a23123a5a0e2bfbde8549e9f39d51d5da2323e9792f733f
MD5 36903dbd57db52cfc920a252fd7699a4
BLAKE2b-256 f06bc0ecc2624930947237b4e6dcb244f80f7b002a2f2002bbb744715b7f0c8f

See more details on using hashes here.

File details

Details for the file clawid-0.2.4-py3-none-any.whl.

File metadata

  • Download URL: clawid-0.2.4-py3-none-any.whl
  • Upload date:
  • Size: 37.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.2

File hashes

Hashes for clawid-0.2.4-py3-none-any.whl
Algorithm Hash digest
SHA256 af4d05b579b991973ba189b945a61b53f1a444b49a06be516d2b297c4159fbce
MD5 bd5424e9751f461cb6bd4eb68e8f2e53
BLAKE2b-256 d12d5d056fbc2ac62afc39fa8abdffcfb2cd6bbc03aa13f7579abc7bcadd9bf7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page