feat([issue-912]): regenerate gallery images to defeat SynthID watermarks#958
Merged
Conversation
… watermarks The lossless cleaner only strips the C2PA caBX chunk + median/sharpen, which SynthID survives by design. Add a post-hoc, history-only 'Regenerate' action beside 'Clean' in the gallery lightbox that round-trips the image through the existing local-FLUX img2img path at low denoise (~0.4), overwriting the per-pixel watermark with fresh sampling while preserving composition. - regen.js: backend-availability gate (FLUX.2 venv health / mflux binary), candidate ordering (source model first, then fast distilled), and pure param assembly reusing the source's own prompt + dimensions. - generateImage/buildSidecarMeta: thread regenOf to stamp regenerated/ regenSteps/regenStrength/regenModelId + cleanedFrom (so the lightbox variant group toggles it as 'Regenerated'). - Route: GET /regen/availability (UI gate) + POST /:filename/regenerate (enqueues a normal local image job through the GPU lane — a separate lane would contend for the same MLX runtime and OOM, so reusing it is correct). - UI: Regenerate button shown only when the local FLUX backend is installed. Refs #912
…tton handlers /simplify cleanups: run the source sidecar + dimension reads concurrently in the regenerate route (no data dependency), and extract the shared guard/try-finally/close pattern behind the Clean and Regenerate buttons into one runBusyAction helper instead of copy-pasting it.
…-lineage guards Address review (codex + claude): - PR-blocker (codex): normalizeImage dropped the new regenerated/regen* sidecar fields, so the gallery's normalized items never carried the discriminator and regen variants rendered as 'Cleaned' in the real UI. Thread the fields through normalizeImage and add a 'Regenerated from …' branch to the lightbox lineage describer. Added a composed normalize→computeImageVariantGroup regression test (the original test used raw objects, missing the normalization layer). - buildSidecarMeta only stamps regenerated/cleanedFrom when the init image actually resolved — a source that failed to resolve degrades to txt2img and must not falsely claim 'regenerated: true'. - regen availability now re-checks when the Settings drawer closes (via reloadBackends), so installing the FLUX venv mid-session reveals the action without a hard reload.
…iant grouping at root Address codex iteration-2 review (both PR-blocking): - Restrict regen capability to FLUX.2 + legacy-mflux-on-macOS. The broader diffusers family (Z-Image/ERNIE/HiDream/Qwen) is excluded because z_image_turbo.py explicitly falls back to txt2img + ignores the init image when a model has no i2i sibling — the JS can't know the round-trip happened, so stamping regenerated:true there would be a false lineage claim. - Anchor the regen's grouping lineage (cleanedFrom/regenOf) at the ROOT original (sourceMeta.cleanedFrom || filename) so regenerating a cleaned or already-regenerated variant produces a sibling that groups under the family, not an orphan; pixels still come from the clicked image.
This was referenced Jun 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a post-hoc, history-only Regenerate action to the image gallery lightbox (next to Clean) that defeats SynthID watermarks the only honest way: by round-tripping the image through a local FLUX model.
The existing Clean only strips the C2PA
caBXchunk + median/sharpen, which SynthID (Google's invisible per-pixel watermark) survives by design. Regenerate runs the source image through the already-present local-FLUX img2img path at low denoise (~0.4 default, 0.2–0.6), so composition holds but the per-pixel signal is overwritten by fresh sampling. It reuses the source image's own prompt and dimensions.GET /api/image-gen/regen/availabilitydrives the gate;POST /api/image-gen/:filename/regenerate400s with an actionable message when no runner exists. Confirmed available on the 128GB machine (Flux2KleinPipelineimports cleanly).regenerated: true,regenSteps,regenStrength,regenModelId(the issue's contract) pluscleanedFromso the variant grouping picks it up.Implementation reuses the proven
generateImage/mediaJobQueueimg2img pipeline — the only new render-path code is theregenOflineage stamp threaded throughbuildSidecarMeta. Newserver/services/imageGen/regen.jsowns the backend-availability gate, candidate ordering (source model first, then fast distilled), and pure param assembly.Closes #912
Test plan
server/services/imageGen/regen.test.js— candidate ordering, regen capability/availability resolution (venv healthy / not installed / source-model preference), pure param assembly (prompt + dims fallbacks, regenOf).server/services/imageGen/local.test.js—buildSidecarMetastamps regen lineage whenregenOfis set and omits it otherwise.server/routes/imageGen.test.js— availability endpoint, out-of-range-strength 400, missing-source 404.client/src/components/media/variants.test.js— regen variants label as "Regenerated" and coexist with cleaned variants under one source.