Nodes/ComfyUI-BlindWatermark/Decode Blind Watermark
ComfyUI Node

Decode Blind Watermark

Extract the Invisible Watermark — If You Kept the Seed

By lihaoyun6·Created about a year ago·Updated 12 months ago· 18
Decode Blind Watermark
  • image
  • watermark
original_seed0

This is the other half of the pack: Apply Blind Watermark hides a logo in an image, and this node drags it back out. Feed it a watermarked image plus the seed you used at encode time, and out pops the recovered watermark as an image. It's the proof-of-provenance step - the reason you bothered to embed anything in the first place.

Part of ComfyUI-BlindWatermark by lihaoyun6, the CPU-only wrapper around fire-keeper/BlindWatermark. No models, no GPU, no external service - everything happens locally on the exact same algorithm that encoded it.

How it works

Decoding is the encode process run in reverse. The node derives the same two shuffle keys from your original_seed (via a CRC32 hash, split into two halves), does the same one-level Haar wavelet transform and 6×6 block split on the image, and for each block reads the DCT + SVD and checks which side of the modulation boundary the largest singular value landed on. That's one watermark bit per block. It reads all three YUV channels and blends them together, so the recovered watermark is effectively an average of three noisy readings - which is why mild edits to the image degrade the result gracefully instead of destroying it.

The inputs

  • image - the watermarked image, ideally as close to the original as possible.
  • original_seed - must match the seed used by the encode node. This is the whole security model: without it, the extracted pixels are unshuffled noise.

Output is a watermark image tensor. For a default encode it comes back as a 64×64 RGB image; wire it into a Preview or Save Image node to see it.

What this node can and can't recover

DWT-DCT-SVD watermarks are genuinely resilient to the boring edits people make: JPEG re-compression, resizing within reason, mild cropping, small color shifts. That's the design goal of the algorithm and it works.

Here's the honest part: it will not survive re-generation. Someone running your image through img2img, a denoise pass, or any diffusion-based cleanup will obliterate the mark - that's exactly the technique communities use to strip SynthID, and it works on this kind of watermark too. So this node is great for you proving your unmodified outputs, and useless against a determined person who knows it's there. Don't build a business on it.

Also note the basic decode node hardcodes the encode defaults: strength 30, block size 6, watermark 64×64, one wavelet level. If you encoded with Apply Blind Watermark (Advanced) at non-default settings, this node will produce garbage. Use the Advanced decode node with matching parameters instead.

Installing

Manager → search "ComfyUI-BlindWatermark", or manually:

cd ComfyUI/custom_nodes
git clone https://github.com/lihaoyun6/ComfyUI-BlindWatermark
cd ComfyUI-BlindWatermark
pip install -r requirements.txt

Then restart. The requirements (pillow, opencv-python, numpy, pywavelets, numba) are all CPU packages; the first run takes a moment while numba compiles. If your extracted watermark is faint noise, you changed a parameter between encode and decode, or the image got re-generated. Check the seed first - that's the failure mode nine times out of ten.

CategoryBlindWatermark/decode

Inputs (2)

NameTypeDefaultDescription
imageIMAGE
original_seedINT00–1125899906842624

Outputs (1)

NameTypeDescription
watermarkIMAGE