Nodes/comfyui-save-image-watermark/Save Image (Watermark) πŸ’§
ComfyUI Node

Save Image (Watermark) πŸ’§

Save Image (Watermark) πŸ’§

By aicuaiΒ·Created 9 months agoΒ·Updated 2 days agoΒ· 3
Save Image (Watermark) πŸ’§
  • images
  • watermark_image
  • watermark_image_mask
  • image
  • filename
  • content_hash
β—„filename_prefixaicutyβ–Ί
β—„file_formatβ–Ύβ–Ί
β—„save_tobothβ–Ί
β—„watermark_image_positionbottom_leftβ–Ί
β—„watermark_image_scale0.15β–Ί
β—„watermark_image_opacity1.00β–Ί
β—„watermark_textΒ© AICUβ–Ί
β—„watermark_text_enabledtrueβ–Ί
β—„watermark_text_positionbottom_rightβ–Ί
β—„watermark_text_opacity0.90β–Ί
β—„watermark_text_size24β–Ί
β—„watermark_text_color#FFFFFFβ–Ί
β—„dynamic_textβ€”β–Ί
β—„invisible_watermarkβ–Ί
β—„invisible_watermark_enabledfalseβ–Ί
β—„embed_workflowtrueβ–Ί
β—„embed_metadatatrueβ–Ί
β—„metadata_json{}β–Ί
β—„jpeg_quality95β–Ί
β—„webp_quality90β–Ί

The name undersells this one. "Save Image (Watermark)" from the aicuai/comfyui-save-image-watermark pack isn't just a fancier SaveImage - it's a three-in-one finishing node. It stamps a visible logo, burns in a text credit, and can bury a hidden message in the least significant bits of the PNG, then writes provenance metadata on top. It's a drop-in replacement for ComfyUI's built-in save node, so it slots in as the last stop on the chain: [KSampler] β†’ [VAEDecode] β†’ [Save Image (Watermark) πŸ’§].

Why reach for it? If you're posting gens publicly - social feeds, a gallery, a Discord server - you want a logo and a credit on the image without a second manual pass in Photoshop. And if you want to keep a lightweight provenance story for your own work (or just be a nerd about it), the invisible LSB channel plus a SHA-256 hash covers it. It's by AICU Japan, the folks behind the ComfyUI Master Guide, Apache 2.0, and it pulls in no dependencies beyond the Pillow/NumPy/PyTorch that already ship with ComfyUI.

How it works

Fixed processing order: the logo blends in first (bottom layer) using result = base * (1 - mask * opacity) + logo * (mask * opacity), the text watermark composites on top, the invisible watermark embeds last, then the file saves. Three outputs come out the right side: image (the watermarked tensor, forced back to RGB), filename, and content_hash - a SHA-256 hex of the saved PNG you could drop into a manifest.

The inputs that matter

  • images (IMAGE, required) - your VAEDecode output. Only the required pair is filename_prefix (default aicuty) and file_format (PNG/JPEG/WEBP).
  • watermark_image and watermark_image_mask - both come from a single LoadImage node. The mask is the trap: wire only the IMAGE output and your logo's transparent areas composite as black. Get both wires.
  • watermark_image_scale (default 0.15), watermark_image_opacity, watermark_image_position (bottom_left default; tile repeats the logo across the whole frame).
  • watermark_text (default "Β© AICU"), watermark_text_size (8–128px), watermark_text_color, opacity, position. dynamic_text appends straight onto watermark_text - handy for injecting a seed or batch ID from another node.
  • invisible_watermark plus invisible_watermark_enabled - the LSB steganography.
  • save_to - output_folder, browser_download, or both (default). Metadata flags (embed_workflow, embed_metadata, metadata_json) and jpeg_quality/webp_quality round it out.

The invisible watermark is classic LSB: your message becomes UTF-8 bits written into the least significant bit of each R, G, B channel, scanning from the top-left pixel, with the alpha channel left alone. Capacity is roughly (width Γ— height Γ— 3) / 8 bytes, and a Β±1 shift per channel is invisible to the eye. But anything lossy - JPEG save, resize, crop, rotate, color tweak - scrambles it completely. The pack's own Photoshop test showed the top-left LSB block surviving edits made elsewhere on the canvas, so PNG re-saves are fine but where you edit matters. Don't trust it as security: no encryption, a fixed embed position, and anyone with the same algorithm can read it. It's an experiment and a toy, not DRM - the README is admirably upfront about that.

Install

ComfyUI Manager β†’ Install Custom Nodes β†’ search watermark or aicu, install, restart. Or manually:

cd ComfyUI/custom_nodes
git clone https://github.com/aicuai/comfyui-save-image-watermark.git

No model files to download, no pip step - the requirements (Pillow, NumPy, PyTorch) are all already present. Restart and it lives under AICU β†’ Save.

Gotchas

  • Forgot watermark_image_mask? Black boxes where your logo should be transparent.
  • Gallery demands JPEG? The invisible watermark is gone for good. If you embed one, file_format stays PNG.
  • The image output is RGB - don't go looking for alpha downstream.
  • The node computes both the pre- and post-watermark hashes internally, but only returns the watermarked content_hash. If you want the before/after comparison, keep the original hash yourself.
CategoryAICU/Save

Inputs (23)

NameTypeDefaultDescription
imagesIMAGEβ€”
filename_prefixSTRINGaicutyβ€”
file_formatCOMBO3 options: PNG, JPEG, WEBP
save_tooptCOMBOboth3 options: output_folder, browser_download, both
watermark_imageoptIMAGEβ€”
watermark_image_maskoptMASKβ€”
watermark_image_positionoptCOMBObottom_left6 options: bottom_right, bottom_left, top_right, top_left, center, tile
watermark_image_scaleoptFLOAT0.150.01–1β€”
watermark_image_opacityoptFLOAT1.000–1β€”
watermark_textoptSTRINGΒ© AICUβ€”
watermark_text_enabledoptBOOLEANtrueβ€”
watermark_text_positionoptCOMBObottom_right6 options: bottom_right, bottom_left, top_right, top_left, center, tile
watermark_text_opacityoptFLOAT0.900–1β€”
watermark_text_sizeoptINT248–128β€”
watermark_text_coloroptSTRING#FFFFFFβ€”
dynamic_textoptSTRINGβ€”
invisible_watermarkoptSTRINGβ€”
invisible_watermark_enabledoptBOOLEANfalseβ€”
embed_workflowoptBOOLEANtrueβ€”
embed_metadataoptBOOLEANtrueβ€”
metadata_jsonoptSTRING{}β€”
jpeg_qualityoptINT951–100β€”
webp_qualityoptINT901–100β€”

Outputs (3)

NameTypeDescription
imageIMAGEβ€”
filenameSTRINGβ€”
content_hashSTRINGβ€”