To Signed Image
When an image needs zero to mean 'nothing happened'
- image
- signed_image
ComfyUI's standard IMAGE type is a 0..1 convention: zero is black, one is white, and values outside that range are meaningless to most nodes. That's great for displayable images and quietly wrong for signal processing. A wavelet coefficient, a chroma plane, a filter response - these want zero to mean "nothing here", with data on both sides. To Signed Image is the doorway to that world: it takes a normal IMAGE and converts it to the pack's SIGNED_IMAGE type, a zero-centered, nominally -1..1 tensor where zero is neutral gray.
The mechanism is one line of math. signed = image * 2 - 1. Linear, reversible, and exactly invertible - run the result back through To Unsigned Image in clamp mode and you get your original image back bit for bit. Nothing is quantized, nothing is clipped; this is a pure re-mapping of the value range. That exact invertibility is why the pack describes the two conversions as a round trip: IMAGE → SIGNED_IMAGE → IMAGE loses nothing as long as you use clamp on the way out.
The one input and the one output. Required input image (IMAGE), output signed_image (SIGNED_IMAGE). There are no knobs. If you can feed an image, you can run this node.
Why you'd actually reach for it. Two cases. First, you're using a downstream pack that expects SIGNED_IMAGE on its input - the README's own example is comfyui-wavelet-2d, a sibling pack by the same author that produces and consumes this same socket type. Second, you're doing your own signed math and want to be explicit about the convention before you wire something into it. Here's the thing worth internalizing about this node: SIGNED_IMAGE is not a wrapper type, it's just a socket-type name sitting on an ordinary [B,H,W,C] tensor. Any pack can produce or consume it just by using the same type string - which is exactly how a whole family of signal-processing packs can interoperate without depending on each other's code. It's a convention, not a class.
And there's the caveat that follows. Because it's a convention, nothing validates it. The node assumes your input is really in 0..1, and if you feed it something already out of range the * 2 - 1 just pushes it further out. Garbage in, signed garbage out. Also note: you do not need this node before Image Subtract - that node does the conversion internally, since a difference of two 0..1 images already falls in -1..1. Reaching for To Signed Image there is redundant. You need it when you're handing signed data to a node that demands the type, or when you want the conversion as an explicit step in the graph for readability.
Install. The whole pack installs the same way, and it's about as light as a ComfyUI install gets:
cd ComfyUI/custom_nodes
git clone https://github.com/NobutakaKuroki/comfyui-signed-image
Restart ComfyUI. No extra Python dependencies (the project's dependency list is empty) and no models to download. Through ComfyUI Manager, search "comfyui-signed-image".
This is a plumbing node - one input, one output, no widgets - so there's not much to get wrong. The only real failure mode is conceptual: forgetting which side of the conversion you're on and treating SIGNED_IMAGE values as if they were still 0..1. If the output of a signed pipeline looks inverted or gray when you preview it, that's not this node - that's a clamp preview doing its job, and the fix lives in Preview Signed Image.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| signed_image | SIGNED_IMAGE | — |