TS Edit Align
Your Qwen Edit Came Back Three Pixels Off — Here's How to Put It Back
- image
- source
- image
The problem you only notice once you try to composite
Edit models don't patch an image, they re-emit it. You hand Qwen-Image-Edit or Flux Kontext a photo plus "remove the lamp post", and what comes back is a new frame that resembles the old one. Close, not identical. Nobody asked for the wall texture to move, but it moved.
You notice when you try to lay the edit back over the original - slider compare, alpha blend, a composite where the untouched half must stay pixel-exact. Then you see it: a double edge, faint ghosting everywhere, worst at the frame border. The edit is a couple of pixels to the side and maybe half a percent larger. That's the model's own error, not wiring. Even handing it a latent sized exactly like the reference leaves a fractional zoom, which is why Qwen's release notes list mitigated drift as a headline fix.
TS Edit Align measures that drift and undoes it.
What it actually does
Three steps:
Same frame. The edit is resized to the source's exact dimensions. An independent stretch per axis is an affine map, so undoing the model's grid rounding this way is exact.
Measure. Both images get reduced to luma, cut into overlapping 96-pixel tiles, and each tile gets a phase-correlation pass with a sub-pixel peak refinement. That's a field of local offsets: where did this patch move. Then a least-squares fit of scale and offset per axis, run four times, dropping tiles whose residual is far from the consensus. An edit is local, so the edited tiles are the outliers and get thrown out automatically; the tiles that didn't change vote on the transform.
Undo. One bicubic warp of the full-resolution edit with the inverse map. The measure-and-warp cycle runs twice, because the second pass mops up what the first estimate missed. Estimation happens on a downscaled copy (long side capped at 1024); the warp is full size.
The inputs that matter
image is the edit, straight out of VAE Decode. source is the original - and this is the one that trips people up, because it's optional. Leave it unconnected and the node passes your image through untouched, printing "no source connected - passed through". It won't error, so a miswired graph just looks like a node that does nothing.
output_size defaults to source: the edit comes back at the original's size, ready to lie on it pixel for pixel. Switch to edit and the size the model rendered at is kept - the source gets stretched up to that instead - so a small photo restored at a larger size doesn't get squeezed back down. Use edit when an upscaler follows, source when you're blending back onto the original.
max_shift (1–128, default 24) is the largest drift, in output pixels, that the node will believe. Tiles displaced further are treated as edited territory and ignored. If your offset really is bigger and the node reports it measured almost nothing, that number is why.
The output is a single image socket, plus a one-line status - corrected shift +2.81, -0.42 px, scale +0.51% / +0.49% (up to 5.0 px at the edge), 142 tiles. Read that line. It's the honest answer to whether the node did anything.
Installing it
In ComfyUI Manager, search Timesaver and install the pack, then restart. Manually:
cd ComfyUI/custom_nodes
git clone https://github.com/AlexYez/comfyui-timesaver
cd comfyui-timesaver
python -m pip install -r requirements.txt
Use the same interpreter ComfyUI runs on - on Windows portable that means python_embeded\python.exe. Now the caveat: this node is one of 85 in a pack whose core requirements include transformers>=5.2.0, openai-whisper and opencv-python-headless. You're pulling a transformers floor and a Whisper install to fix a 3-pixel offset. That's the trade - the node itself needs nothing beyond torch.
Where it goes wrong
A flat or rewritten image gets a resize and nothing else, with the status line "not enough unchanged texture to measure - resized only". Phase correlation needs texture to lock onto, and enough agreeing tiles to trust a fit. Correct behaviour, not a bug - but it means the node can quietly be a no-op on a heavy restyle.
Batches. It aligns frame by frame, and a source with fewer frames clamps to its last one - so one clean reference aligns a whole clip.
Don't put it after an upscaler. Align at source size, then upscale.
And it isn't a substitute for masking. If the unedited pixels must survive byte-for-byte, an edit model still can't promise it. This gets you from "visibly off" to "you can't tell", not to bit-exact.
One last thing: this pack has no community footprint - no threads, no tutorials. Not a quality verdict, just don't expect to google your way out of trouble. The status line is the documentation.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | The edited image, straight from VAE Decode (a batch is aligned frame by frame). | |
| max_shift | FLOAT | 241–128 | Largest drift (pixels of the output) the node will correct. Tiles moved further count as edited. |
| output_size | COMBO | source | source: the edit is brought to the original's size and lies on it pixel for pixel. edit: keep the size the model rendered at (no generated detail lost) and align it to the original stretched to that size — better before an upscaler, e.g. for small photos. |
| sourceopt | IMAGE | The original the edit was made from. Not connected = pass through. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | The edit, in the original's position, at the chosen size. |