mirror of
https://github.com/wiltodelta/remove-ai-watermarks.git
synced 2026-08-19 12:07:13 +02:00
Renaming it strands every pip install and every pinned dependency on it, including the ComfyUI node package, and the console script has the same property since users have it on PATH. Recorded at the name itself, where whoever considers changing it will be looking. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
245 lines
8.9 KiB
TOML
245 lines
8.9 KiB
TOML
[project]
|
|
# This name is the published PyPI distribution, not a local label: changing it
|
|
# strands every `pip install remove-ai-watermarks` and every pinned dependency
|
|
# on it, including the ComfyUI node package. The console script below carries
|
|
# the same weight, since users have it on PATH.
|
|
name = "remove-ai-watermarks"
|
|
version = "0.26.3"
|
|
description = "AI watermark remover for visible, invisible, and provenance marks in images and video"
|
|
readme = "README.md"
|
|
requires-python = ">=3.10.1"
|
|
license = {text = "Apache-2.0"}
|
|
keywords = [
|
|
"ai-watermark",
|
|
"ai-watermark-remover",
|
|
"watermark-remover",
|
|
"watermark-removal",
|
|
"remove-watermark",
|
|
"synthid",
|
|
"c2pa",
|
|
"content-credentials",
|
|
"nano-banana",
|
|
"gemini",
|
|
"gemini-watermark",
|
|
"ai-metadata",
|
|
"metadata-removal",
|
|
"provenance",
|
|
"exif",
|
|
"stable-diffusion",
|
|
"comfyui",
|
|
"ai-detection",
|
|
]
|
|
classifiers = [
|
|
"Development Status :: 4 - Beta",
|
|
"Environment :: Console",
|
|
"Intended Audience :: Developers",
|
|
"Intended Audience :: End Users/Desktop",
|
|
"License :: OSI Approved :: Apache Software License",
|
|
"Operating System :: OS Independent",
|
|
"Programming Language :: Python :: 3 :: Only",
|
|
"Programming Language :: Python :: 3.10",
|
|
"Programming Language :: Python :: 3.11",
|
|
"Programming Language :: Python :: 3.12",
|
|
"Programming Language :: Python :: 3.13",
|
|
"Programming Language :: Python :: 3.14",
|
|
"Topic :: Multimedia :: Graphics",
|
|
"Topic :: Multimedia :: Graphics :: Graphics Conversion",
|
|
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
"Topic :: Scientific/Engineering :: Image Processing",
|
|
"Topic :: Security",
|
|
"Topic :: Utilities",
|
|
]
|
|
dependencies = [
|
|
"pillow>=10.0.0",
|
|
"piexif>=1.1.3",
|
|
"click>=8.0.0",
|
|
"python-dotenv>=1.0.0",
|
|
# Official C2PA reader (Content Authenticity Initiative, MIT/Apache-2.0). The
|
|
# primary, spec-tracking manifest parser for the identify/metadata path; the
|
|
# hand-rolled caBX/CBOR scanner in _internal/c2pa.py is kept only as a fallback for
|
|
# synthetic/partial blobs the validator rejects. Binary wheel (Rust), but the
|
|
# import is light (no torch/numpy) so it fits the dependency-light identify
|
|
# host. Prebuilt wheels cover the full CI matrix (linux/macos/windows).
|
|
"c2pa-python>=0.35.0",
|
|
]
|
|
|
|
[project.optional-dependencies]
|
|
pixels = [
|
|
"numpy>=1.24.0",
|
|
"opencv-python-headless>=4.8.0",
|
|
]
|
|
# Optional HEIC/AVIF pixel decode. Metadata scanning handles these containers
|
|
# without this plugin; combine `heif` with any pixel feature only when needed.
|
|
heif = [
|
|
"pillow-heif>=0.13.0",
|
|
]
|
|
visible = ["remove-ai-watermarks[pixels]"]
|
|
# Video visible removal uses the shared pixel runtime. PyAV packetizes processed
|
|
# VFR frames with explicit PTS before system ffmpeg encodes them. PyAV 18 requires
|
|
# Python 3.11; the 16.x wheel line still covers Python 3.10.
|
|
video = [
|
|
"remove-ai-watermarks[visible]",
|
|
"av>=16,<17; python_version < '3.11'",
|
|
"av>=18,<19; python_version >= '3.11'",
|
|
]
|
|
# Open DWT-DCT watermarks used by Stable Diffusion / SDXL / FLUX. The in-tree
|
|
# decoder avoids the upstream invisible-watermark package's mandatory torch and
|
|
# non-headless OpenCV dependencies.
|
|
detect = [
|
|
"remove-ai-watermarks[pixels]",
|
|
"PyWavelets>=1.1.1",
|
|
]
|
|
diffusion = [
|
|
"remove-ai-watermarks[pixels]",
|
|
# A CUDA-enabled torch build is required: invisible-watermark removal has no
|
|
# CPU, MPS or XPU path. The default PyPI wheel carries CUDA on Linux/Windows;
|
|
# on macOS there is no CUDA build and this extra installs only for the
|
|
# non-diffusion imports it shares.
|
|
"torch>=2.0.0",
|
|
"diffusers>=0.38.0",
|
|
# diffusers 0.38's auto-pipeline registry imports ``Qwen3VLForConditional
|
|
# Generation`` (its ``nucleusmoe_image`` pipeline), which only exists in
|
|
# transformers 5.x -- so ``from diffusers import AutoPipelineForImage2Image``
|
|
# fails on transformers 4.x. The real SDXL-loading break was NOT transformers
|
|
# 5.x but the tokenizers *release candidate* (0.23.0rc0) that the global
|
|
# ``prerelease = "allow"`` drags in: its CLIP tokenizer raises
|
|
# ``RobertaProcessing.__new__() got an unexpected keyword argument 'cls'``.
|
|
# Cap tokenizers to the stable 0.22 line (transformers 5.x accepts
|
|
# >=0.22,<=0.23.0) so the rc is excluded while SDXL still loads.
|
|
"transformers>=5,<6",
|
|
"tokenizers>=0.22,<0.23",
|
|
"accelerate>=0.25.0",
|
|
"safetensors",
|
|
]
|
|
# Full two-stage high-fidelity profile: Qwen-Image-2512 Lightning + DiffSynth
|
|
# Canny ControlNet for the frame, then SAM-masked Z-Image Turbo face repair.
|
|
# CUDA-only and intentionally separate from the normal diffusion extra because the
|
|
# additional model stack and DiffSynth runtime are large.
|
|
qwen-zimage = [
|
|
"remove-ai-watermarks[diffusion]",
|
|
"diffsynth>=2.0.17,<3",
|
|
"torchvision>=0.20.0",
|
|
]
|
|
# Adobe TrustMark decoder -- the open, keyless watermark behind Adobe Durable
|
|
# Content Credentials (soft-binding alg ``com.adobe.trustmark.P``). Optional
|
|
# because it pulls torch and downloads model weights on first use. identify()
|
|
# guards the import and skips the TrustMark signal when absent.
|
|
trustmark = [
|
|
"trustmark>=0.8.0",
|
|
]
|
|
# Universal region eraser backend -- big-LaMa via onnxruntime (Carve/LaMa-ONNX,
|
|
# Apache-2.0). CPU, no torch. Model (~200 MB) is downloaded on first use and
|
|
# cached by huggingface_hub; it is never bundled in this repo. The default cv2
|
|
# eraser backend needs none of this.
|
|
lama = [
|
|
"remove-ai-watermarks[visible]",
|
|
# ONNX Runtime 1.24 dropped CPython 3.10 wheels; keep the project's
|
|
# supported 3.10 line on the last compatible release series.
|
|
"onnxruntime>=1.16.0,<1.24; python_version < '3.11'",
|
|
"onnxruntime>=1.16.0; python_version >= '3.11'",
|
|
"huggingface-hub>=0.20.0",
|
|
]
|
|
# Lightweight inpaint backend -- MI-GAN via onnxruntime (andraniksargsyan/migan,
|
|
# MIT). CPU, no torch. Model (~28 MB) downloaded on first use and cached by
|
|
# huggingface_hub; never bundled. ~700-950 MB peak RAM / ~0.19 s/call -- the
|
|
# memory-tight learned tier (vs big-LaMa's ~4.7 GB). Select it explicitly when
|
|
# LaMa, the quality-first `auto` choice, is too large. Same runtime as `lama`.
|
|
migan = [
|
|
"remove-ai-watermarks[visible]",
|
|
"onnxruntime>=1.16.0,<1.24; python_version < '3.11'",
|
|
"onnxruntime>=1.16.0; python_version >= '3.11'",
|
|
"huggingface-hub>=0.20.0",
|
|
]
|
|
dev = [
|
|
"remove-ai-watermarks[video]",
|
|
"remove-ai-watermarks[detect]",
|
|
"pytest>=8.0.0",
|
|
"pytest-cov>=4.1.0",
|
|
"pytest-xdist>=3.5.0",
|
|
"packaging>=24.0",
|
|
"ruff>=0.4.0",
|
|
"pyright>=1.1.0",
|
|
"invisible-watermark>=0.2.0",
|
|
# maintain.sh helpers; they only support newer Pythons, so gate them by
|
|
# marker to keep the py3.10 resolution (and CI matrix) solvable.
|
|
"uv-outdated>=0.1.0; python_version >= '3.12'",
|
|
"uv-secure>=0.12.0; python_version >= '3.12'",
|
|
]
|
|
# ``qwen-zimage`` already pulls ``diffusion``; naming both would suggest diffusion is
|
|
# independently sufficient for a removal, which it is not.
|
|
all = ["remove-ai-watermarks[video,heif,detect,trustmark,qwen-zimage,lama,migan]"]
|
|
|
|
[project.scripts]
|
|
remove-ai-watermarks = "remove_ai_watermarks.cli:main"
|
|
|
|
[project.urls]
|
|
Repository = "https://github.com/wiltodelta/remove-ai-watermarks"
|
|
|
|
[build-system]
|
|
requires = ["hatchling"]
|
|
build-backend = "hatchling.build"
|
|
|
|
[tool.hatch.build.targets.wheel]
|
|
packages = ["src/remove_ai_watermarks"]
|
|
|
|
[tool.hatch.build.targets.sdist]
|
|
# Keep the source distribution small and public-safe: ship tracked source and
|
|
# metadata, not corpora or local research/session artifacts. The wheel ships
|
|
# only src/.
|
|
include = [
|
|
"/src",
|
|
"/LICENSE",
|
|
"/README.md",
|
|
"/pyproject.toml",
|
|
]
|
|
exclude = [
|
|
"/data",
|
|
"/tmp",
|
|
"/.sc",
|
|
]
|
|
|
|
[tool.pytest.ini_options]
|
|
testpaths = ["tests"]
|
|
pythonpath = ["src"]
|
|
addopts = "-v --tb=short"
|
|
|
|
[tool.ruff]
|
|
target-version = "py310"
|
|
line-length = 120
|
|
exclude = ["_refs"]
|
|
extend-exclude = ["*.md"]
|
|
|
|
[tool.ruff.lint]
|
|
select = ["E", "F", "B", "I", "S", "UP", "SIM", "RET", "COM", "C4", "G", "PT", "PIE", "T20", "DTZ", "ICN", "TCH", "RUF", "ANN"]
|
|
ignore = [
|
|
"COM812", # missing trailing comma (conflicts with ruff formatter)
|
|
"ANN401", # typing.Any — sometimes unavoidable with third-party libs
|
|
]
|
|
|
|
[tool.ruff.lint.per-file-ignores]
|
|
"scripts/*.py" = ["G004", "S108", "S310", "T20"]
|
|
"tests/*.py" = ["ANN", "S101", "S105", "S106", "S108"]
|
|
"src/remove_ai_watermarks/_internal/watermark_remover.py" = ["S603", "S606", "S607"] # nvidia-smi capability probe
|
|
"src/remove_ai_watermarks/_internal/c2pa.py" = ["S110"] # try-except-pass for corrupt file handling
|
|
|
|
[tool.ruff.format]
|
|
quote-style = "double"
|
|
indent-style = "space"
|
|
|
|
[tool.pyright]
|
|
pythonVersion = "3.10"
|
|
typeCheckingMode = "strict"
|
|
exclude = ["_refs"]
|
|
|
|
[[tool.pyright.executionEnvironments]]
|
|
root = "tests"
|
|
extraPaths = ["."]
|
|
reportAttributeAccessIssue = false
|
|
reportOptionalSubscript = false
|
|
reportOptionalMemberAccess = false
|
|
reportArgumentType = false
|
|
reportUnknownMemberType = false
|
|
reportUnknownArgumentType = false
|
|
reportUnknownVariableType = false
|
|
reportMissingTypeArgument = false
|