Nodes/Blind_watermark_Comfyui/πŸ“ Embed Text Watermark
ComfyUI Node

πŸ“ Embed Text Watermark

Stamp 'Copyright 2026' into the pixels themselves β€” Embed Text Watermark

By TianDongLΒ·Created 11 months agoΒ·Updated 11 months agoΒ· 22
πŸ“ Embed Text Watermark
  • image
  • watermarked_image
  • wm_length
  • info
β—„watermark_textCopyright 2024β–Ί
β—„password_img1β–Ί
β—„password_wm1β–Ί
β—„strength1.0β–Ί
β—„processesautoβ–Ί
β—„d1_override0β–Ί
β—„d2_override0β–Ί

If you've ever wanted to prove an image was yours without slapping a visible watermark across it, this is the node. It takes a short text string - a copyright notice, your username, an ID - and writes it into the image's frequency domain so that it's invisible to the eye but recoverable with the right key. It's the text sibling of the pack's image-watermark node, and it's the one most people reach for first because text is the easiest payload to actually use.

The honest limitations up front: the text survives re-encoding, scaling, mild rotation and cropping, but not aggressive re-painting or heavy filtering. And it is not a phone-home tracker - whoever has the watermarked image and doesn't have your passwords gets nothing out of it. Think of it as a tamper-evident signature, not DRM.

How it works

Same engine as the pack's other embed node - DWT-DCT-SVD frequency-domain embedding, based on the vendored guofei9987/blind_watermark library. Haar wavelet transform, 4Γ—4 blocks of the low-frequency band, DCT, then SVD quantizes the top singular values to encode one bit per block, spread across all three color channels. The string is converted to its UTF-8 bits, those bits are shuffled with password_wm, and the block placement is shuffled with password_img.

Two things to know about capacity. First, capacity scales with image size: roughly one bit per 4Γ—4 block of the approximation band, so a 512Γ—512 image holds on the order of 4,000 bits - around 500 bytes. That's why the README's "keep it under 100 characters" rule exists. Second, the node's wm_length output tells you exactly how many bits were used. You need that number to extract the text later, which is why it's an output at all.

The inputs that matter

  • image - your carrier. Keep it β‰₯ 512Γ—512 and clean; a heavily compressed input starts you in a hole.
  • watermark_text - keep it short and ASCII-lean. Every character costs bits, and long strings need big images or fail the capacity check.
  • password_img / password_wm - the key pair. They must match exactly at extraction time. Both default to 1, which works but is the equivalent of a blank password - anyone who knows the scheme could decode a default-keyed image. Set real values.
  • strength - multiplies the d1/d2 quantization. 1.0 is the balanced default; lower if the watermark shows, higher if extraction fails.
  • d1_override / d2_override - optional fine-tuning, default 0 meaning auto.

The three outputs matter together: watermarked_image is your result, wm_length is the bit count you hand to WatermarkExtractText, and info is a human-readable summary (length in bits, estimated byte count, the passwords, the d1/d2 used). Wire wm_length straight into the extract node's input and you can't lose it.

Install

cd ComfyUI/custom_nodes
git clone https://github.com/TianDongL/Blind_watermark_Comfyui.git
pip install -r requirements.txt
# restart ComfyUI

Or "Blind Watermark" via ComfyUI Manager. CPU-only, no models to download. The actual requirements are numpy, opencv-python, setuptools, PyWavelets, qrcode and pyzbar - the README's pip list is a little out of date, and despite it mentioning blind-watermark, the pack vendors that library's source, so there's no separate install needed.

Troubleshooting

  • Garbled or empty text on extraction - passwords mismatch, wm_length is wrong, or the image got re-encoded (each extra save, especially JPEG, is a few more lost bits). Save as PNG.
  • "Image too small for watermark extraction" on the extract side - you embedded more text than the image could hold. Shorter text, bigger image, or both.
  • Watermark visible - the text is long and strength is high; drop strength to ~0.6 or shorten the string. Long messages push d1/d2 up and start leaving artifacts.
  • Node not appearing - the requirements failed to install or ComfyUI wasn't restarted. Check the console for the pip error before anything else.
CategoryBlindWatermark/Embed

Inputs (8)

NameTypeDefaultDescription
imageIMAGEβ€”
watermark_textSTRINGCopyright 2024β€”
password_imgINT11–999999β€”
password_wmINT11–999999β€”
strengthFLOAT1.00.1–3β€”
processesCOMBOauto7 options: auto, 1, 2, 4, 8, multiprocessing, +1
d1_overrideoptINT00–200Manual d1 parameter (0=auto)
d2_overrideoptINT00–100Manual d2 parameter (0=auto)

Outputs (3)

NameTypeDescription
watermarked_imageIMAGEβ€”
wm_lengthINTβ€”
infoSTRINGβ€”