Nodes/single_image_deducker/single_image_deducker
ComfyUI Node

single_image_deducker

Pull a hidden image out of a carrier, right inside your graph

By arctan90·Created 6 months ago·Updated 6 months ago· 0
single_image_deducker
  • image
  • image
password

single_image_deducker is a steganography decoder, not an AI node. No model to download, no API to call, no key to hunt for - feed it a carrier image that has a hidden image buried in its pixels and it digs the payload back out as a normal IMAGE tensor. The name starts making sense once you learn "duck" is a small Chinese stego toolchain (the node even ships with buttons to the author's online decode tool, tutorials, and a couple of QQ groups). The encode side lives in that ecosystem; this node is the decode side, and it's the only part that lives in ComfyUI.

Why you'd reach for it

It's niche, but if you're in the right place it saves a step nobody else saves. Someone shares a "ducked" image - watermarked, or holding a private image inside a harmless-looking carrier - and instead of saving it to disk, firing up a separate stego app, and loading the result back in, you just drop it in and the recovered image flows straight into whatever comes next: Save Image, an upscaler, img2img, a VAE decode. No file juggling. If you're not trading duck-encoded images, you don't need this - but when you do, there's no other node doing it.

How it works

Classic LSB steganography with a few honest engineering choices. The decoder reads the low bits of each color channel and tries three bit-depths - 2, 6, then 8 - until a valid header parses. One detail worth knowing: it deliberately skips a region in the top-left corner (40% of the width by 8% of the height), because that's where the encoder's watermark/logo lives. The decoder knows not to read payload out of the part of the image that's meant to be a badge.

The payload header is compact: a length, a flag for whether a password was set, and if so a salted SHA-256 hash plus the salt. Password-protected payloads are XOR'd with a keystream derived from your password and salt; give the right one and it decrypts cleanly, get it wrong and you get 密码错误 ("wrong password"). The header also carries the original filename extension, and that's the gate: only png, jpg, jpeg, bmp, and webp are allowed through. Anything else - a hidden video or text file - raises 解码结果不是图片 ("decoded result is not an image"). This node is single-image only, and it means it.

Inputs and outputs

Only two inputs, and one output you'll actually use:

  • image (required, IMAGE) - the carrier. Wire it from a Load Image node (or any image you already have in your graph).
  • password (optional STRING, default empty) - leave it blank unless the source image was protected, in which case the author's tool set a password on encode.
  • Output: image (IMAGE) - the recovered hidden image. Wire it into anything that takes an image. One gotcha: a batched tensor gets flattened to its first frame, so feed it single images, not a video batch.

Install

ComfyUI Manager, search for single_image_deducker - or the manual route:

cd ComfyUI/custom_nodes
git clone https://github.com/arctan90/single_image_deducker

Then restart ComfyUI. Its requirements.txt is just pillow and numpy, which any working ComfyUI already has (torch ships with ComfyUI), so there's no dependency hell and no model files to fetch. This one is refreshingly light in a custom-node ecosystem where half the installs come with a 2GB checkpoint.

Troubleshooting

The errors it throws are the README, in practice:

  • 解码结果不是图片 - the hidden payload is a video or text file, and this node only unpacks images. Use the author's desktop encode/decode tool for those.
  • 密码错误 / 需要密码 - you hit a password-protected payload with the wrong password, or no password at all. Get the real one.
  • Payload-length / capacity errors - the carrier is corrupt, recompressed, or simply not a duck-format stego image. Try the original file; heavily compressed or resized carriers lose their payload and can't be recovered.
  • Import error on startup - the pack isn't in custom_nodes, or pip install -r requirements.txt never ran.

One honest caveat to close on: stego images are a two-way door, and the wider community treats "hidden file inside an image" with justified wariness. This particular node is safe in that it only extracts validated image bytes and errors on everything else - it can't unpack a payload as an executable. But if a stranger hands you a mysterious carrier, the sensible habit is to think about what's inside before you ask a machine to dig it out.

Categorysingle_image_deducker

Inputs (2)

NameTypeDefaultDescription
imageIMAGE
passwordoptSTRING

Outputs (1)

NameTypeDescription
imageIMAGE