Feature (frontend): Add invisible watermark decoder node. by lstein · Pull Request #8967 · invoke-ai/InvokeAI

Summary

Adds a workflow node to decode invisible watermarks previously embedded with the existing Add Invisible Watermark node. Returns the watermark text as a string, or an empty string if no watermark is detected or decoding fails.

invokeai/backend/image_util/invisible_watermark.py

  • Added decode_watermark(image, length=8) classmethod to InvisibleWatermark
  • Uses vendored WatermarkDecoder("bytes", length * 8) with dwtDct — mirrors the encoding path
  • Returns decoded UTF-8 string stripped of null bytes; catches all exceptions and returns ""

invokeai/app/invocations/image.py

  • Added DecodeInvisibleWatermarkInvocation node ("decode_watermark")
  • Inputs: image: ImageField, length: int (bytes, default 8 — matches the default "InvokeAI" watermark)
  • Output: StringOutput with the decoded watermark text

The length parameter must match the byte length of the text used during encoding (e.g., 8 for "InvokeAI").

Related Issues / Discussions

QA Instructions

  1. Create a two-node workflow in which the existing "Add Invisible Watermark" is connected to the new "Decode Invisible Watermark" node.
  2. Feed an image to "Add Invisible Watermark" using its default settings.
  3. Confirm that the "Decode Invisible Watermark" returns "InvokeAI".
  4. Create a two-node workflow in which the "Image Primitive" node is connected directly to "Decode Invisible Watermark".
  5. Feed the workflow an image that does not have a watermark.
  6. Confirm that the output of the decode node is the empty string. ""

Merge Plan

Simple merge.

Checklist

  • The PR has a short but descriptive title, suitable for a changelog
  • Tests added / updated (if applicable)
  • ❗Changes to a redux slice have a corresponding migration
  • Documentation added / updated (if applicable)
  • Updated What's New copy (if doing a release after this PR)