Nodes/ComfyUI-AusBoss/Realign to Source (EXPERIMENTAL πŸ§ͺ) πŸ†Ž
ComfyUI Node

Realign to Source (EXPERIMENTAL πŸ§ͺ) πŸ†Ž

Your Qwen edit came back 5% taller β€” measure it, warp it back

By ausbossΒ·Created 3 months agoΒ·Updated 2 days agoΒ· 64
Realign to Source (EXPERIMENTAL πŸ§ͺ) πŸ†Ž
  • edited
  • source
  • stitcher
  • image
  • empty_mask
  • report
β—„fitzoom + shiftβ–Ί
β—„empty_filledgeβ–Ί
β—„max_zoom20.0β–Ί

The thing nobody warns you about with edit models

Ask Qwen Image 2.1 for a watercolor pass, get a lovely watercolor back, lay it over your source - and the horizon sits 40 px lower and the face is a bit bigger. You didn't ask for a zoom. Nothing in an instruction editor pins the pixels you didn't ask about, so it re-emits the whole frame at slightly different proportions. This goes back to Qwen-Image-Edit's first release: the community's most-upvoted 2509 workaround was to bypass the encoder's forced 1 MP canvas and feed it reference latents you encoded yourself.

That upstream fix is the better one when you're building the graph from scratch. Realign to Source is the other approach: you already have a drifted edit, and this node measures how far it moved and drags it back. Experimental, and fairly labelled - but it's real measurement, no API, no weights, runs on your CPU.

Which you'll want, because the pack's own testing puts style edits about 4% taller on average and up to 12% - 30–40 px at the edges of a 1 MP picture - differently for every seed, while light edits hold within 0.4%. The old Qwen Edit advice doesn't help here: snapping dimensions to a multiple of 112 won't fix it.

The inputs that matter

  • edited - the edit. source - the picture it was made from, at the size the model saw it (in the pack's example, the Image Resize output, not the raw load). One source frame broadcasts across a batch; the result comes out at the source's size.
  • fit - zoom + shift for the usual drift. affine also fixes a slight tilt, at the cost of a warp where a plain cut would have done.
  • max_zoom - the biggest zoom it will undo, in percent, default 20. Past that it's treated as change you meant and left alone, which is right: a 40% zoom is a reframe, not drift.
  • empty_fill - when the edit slid inward, a strip at the edge has no picture in it. edge stretches the nearest pixels in, source fills from your original, gray drops flat gray there for inpainting.
  • stitcher (optional) - the AUSBOSS_STITCHER from Load Image + Pad or Image Crop + Rotate + Pad. Padded before editing? Plug it in: the node measures inside the picture's area and hands back only that area, no padding, no empty edges.

Outputs are image (the realigned frame), empty_mask (white wherever there's nothing - crop it or inpaint it; all black when there's none) and report, one readable line. Wire report into the pack's Show Text and you get this:

realigned: zoom x -0.25%, y +5.24%; shift x +1.0, y +30.1 px; worst corner 61.1 px
(142 of 162 areas agree, fit error 3.2 px); warped once; empty strip 5.0% of the frame;
to keep real picture there, pad the source before editing: bottom 77 px

That last clause is the useful bit - which side ran out of picture, and by how much.

How the measurement works

Both pictures become edge maps - gradient strength normalised by its surroundings - so a restyle, a relight or inverted tones still line up with the source. Textured blocks are then compared by band-limited phase correlation: a coarse pass finds the drift (trying the edit at a few zooms first, in case it came back reframed), then two finer passes refine it after pre-warping the edit by the estimate. A robust fit turns those block shifts into zoom and shift, and blocks that disagree - the boat the model redrew somewhere else - get dropped. It only trusts the answer when at least 10 blocks, and a quarter of them, agree with it.

If the drift is close enough to a whole-pixel shift, the frame is cut straight out of the edit with no resampling: every pixel untouched, the nicest outcome available. Otherwise it's one bicubic warp. All of it runs on CPU in a fraction of a second per 1 MP frame, on the torch ComfyUI already ships.

Installing it

Search the Custom Nodes Manager for AusBoss and install, or:

comfy node install ausboss-nodes
# or, for the newest commits before registry review catches up:
cd ComfyUI/custom_nodes && git clone https://github.com/ausboss/ComfyUI-AusBoss.git

Nothing extra to pip install for this node - the pack declares no dependencies and uses ComfyUI's own Pillow, NumPy, Torch and PyAV. Minimum core is 0.27.1. After an update, restart and hard-refresh with Ctrl+Shift+R, or you'll keep the stale frontend JavaScript. If the classic Manager complains it can't find the ComfyRegistry list, your Channel box is empty - set it to default and retry.

Where people get tripped up

"The edit is 1024x1024 but the source is 832x1216, so it was probably made on a canvas of another shape." That's the trap. Sample on a canvas that isn't the encoder's own latent and the model shrinks the whole picture to fit - a big uniform zoom that isn't drift, and the node deliberately won't undo it. Keep the sampler on the Qwen encoder's latent output.

The report says it left the picture alone (only 4 of 162 areas agree) - the restyle redrew too much to match, or you gave it the wrong source. Nothing breaks; the edit passes through at the source's size.

You still get an empty strip. The drift outpaced your margin. The report names the sides and the pixels needed, plus 16 px of headroom, because the next seed drifts differently. 64 px a side with Load Image + Pad's mirror fill is the recommended start - mirror reads as more of the scene, where gray or stretched pixels tempt the model into zooming to fill them. It costs about 27% more render time at 1 MP.

Running the Qwen Image 2.1 consistency LoRA? Skip the margin and just trim what's left; the pack's measurements put LoRA-plus-no-margin as the most precise path.

And the honest limit: this fixes whole-frame zoom and shift, not shapes the model redrew somewhere new. If you need the guarantee that unmasked pixels never changed, that's still Inpaint Crop β†’ edit β†’ Stitch.

CategoryπŸ†Ž AusBoss/Image

Inputs (6)

NameTypeDefaultDescription
editedIMAGEThe edited picture.
sourceIMAGEThe original picture you edited, at the size the edit model saw it. The result comes out at this size.
fitCOMBOzoom + shiftzoom + shift fixes the usual Qwen drift. affine also fixes a slight tilt.
empty_fillCOMBOedgeIf the edit slid past the edge, a thin strip ends up with nothing in it. edge stretches the nearest pixels into it, source fills it from the original, gray fills it flat gray for inpainting.
max_zoomFLOAT20.01–50The biggest zoom it will undo, in percent. Anything bigger is treated as a change you meant and left alone.
stitcheroptAUSBOSS_STITCHEROptional. Plug in the stitcher from Load Image + Pad πŸ†Ž if you padded the picture before editing. You get your picture back without the padding, with no empty edges.

Outputs (3)

NameTypeDescription
imageIMAGEThe edit, lined up with the original and at its size.
empty_maskMASKWhite where the lined-up edit has nothing (a strip that slid off the edge). All black when there is none.
reportSTRINGHow far the edit had moved and what was done. Plug it into Show Text πŸ†Ž to read it.