feat(invisible): protect text automatically by default (#21)

Mirror protect_faces: protect_text defaults to True in invisible_engine and
watermark_remover, so the SDXL pipeline detects text per image and switches to
Differential Diffusion only when glyphs are found. Text-free inputs fall back to
plain img2img with no differential-pipeline load, so the autonomy is free. The
CLI now exposes a single off-switch --no-protect-text instead of the positive
flag, keeping the interface minimal.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Victor Kuznetsov
2026-05-28 12:24:09 -07:00
co-authored by Claude Opus 4.7
parent a0bf62e601
commit 0eec3001bb
5 changed files with 26 additions and 19 deletions
+8 -8
View File
@@ -461,10 +461,10 @@ def cmd_erase(
help="Cap long side (px) before diffusion; 0 = native (best quality, like raiw.cc). Raise only on GPU/MPS OOM.",
)
@click.option(
"--protect-text",
"--no-protect-text",
is_flag=True,
default=False,
help="Preserve detected text (incl. CJK) via Differential Diffusion. SDXL default pipeline only.",
help="Disable automatic text protection (text/CJK is preserved by default on the SDXL pipeline).",
)
@click.pass_context
def cmd_invisible(
@@ -479,7 +479,7 @@ def cmd_invisible(
hf_token: str | None,
humanize: float,
max_resolution: int,
protect_text: bool,
no_protect_text: bool,
) -> None:
"""Remove invisible AI watermarks (SynthID, StableSignature, TreeRing).
@@ -526,7 +526,7 @@ def cmd_invisible(
guidance_scale=None,
seed=seed,
humanize=humanize,
protect_text=protect_text,
protect_text=not no_protect_text,
max_resolution=max_resolution,
)
elapsed = time.monotonic() - t0
@@ -680,10 +680,10 @@ def cmd_identify(ctx: click.Context, source: Path, no_visible: bool, as_json: bo
help="Cap long side (px) before diffusion; 0 = native (best quality, like raiw.cc). Raise only on GPU/MPS OOM.",
)
@click.option(
"--protect-text",
"--no-protect-text",
is_flag=True,
default=False,
help="Preserve detected text (incl. CJK) via Differential Diffusion. SDXL default pipeline only.",
help="Disable automatic text protection (text/CJK is preserved by default on the SDXL pipeline).",
)
@click.pass_context
def cmd_all(
@@ -701,7 +701,7 @@ def cmd_all(
hf_token: str | None,
humanize: float,
max_resolution: int,
protect_text: bool,
no_protect_text: bool,
) -> None:
"""Remove ALL watermarks: visible + invisible + metadata.
@@ -793,7 +793,7 @@ def cmd_all(
num_inference_steps=steps,
seed=seed,
humanize=humanize,
protect_text=protect_text,
protect_text=not no_protect_text,
max_resolution=max_resolution,
)
console.print(" [green]✓[/] Invisible watermark removed")