Transform Image (mtb)
Pan, zoom, rotate and shear in the graph
- image
- constant_color
- IMAGE
A proper 2D transform node: translate, zoom, rotate, shear, and stretch an image, all in one place, while keeping the output the same tensor shape as the input. If you've ever wanted to nudge a composite over a few pixels, spin an element, or Ken-Burns a still into a slow push-in across a batch of frames, this is the node.
The "keeps the tensor shape" part is the practical bit. Because it hands back an image the same size as it took in, you can drop it mid-graph without breaking everything downstream that expects a fixed resolution - and it's why this shows up so often in animation setups, where you want to animate a transform over a batch without the canvas dimensions drifting.
How it works
It builds a 2D affine transform from your parameters and resamples the image through it. The interesting choices are what happens at the edges (the area exposed when you move or rotate) and which resampling filter it uses.
The inputs that matter
x/y- translation. By default these are in pixels (range ±4096). Positive/negative pushes the image around the frame.zoom- scale factor (1 = no change). Above 1 pushes in, below 1 pulls out.angle- rotation in degrees (±360).shear- slants the image, the skew you'd use for a fake-perspective or italic effect.border_handling- what fills the newly-exposed area:edgesmears the edge pixels outward (default),constantfills withconstant_color, andreflect/symmetricmirror the image back on itself. This is the setting that decides whether a rotated image gets an ugly black corner or a clean fill.filter_type(optional) - resampling quality:nearest(fastest, blocky) up tobicubicandlanczos(best, slowest).bilinearis the balanced default. One catch straight from the node's docs:lanczosandhammingdon't support rotation - if you're rotating, stick tobilinearorbicubic.stretch_x/stretch_yanduse_normalized(optional) - non-uniform scaling, and a toggle to interpretx/yas normalized 0–1 coordinates instead of pixels, handy when you want the same move to scale across different resolutions.
Single IMAGE output.
How to install it
ComfyUI Manager: search MTB Nodes (comfy_mtb), install, restart. Or manually: cd ComfyUI/custom_nodes && git clone https://github.com/melMass/comfy_mtb and restart. Pure Python - nothing to download.
Common issues
The rotation-plus-filter gotcha is the one that surprises people: pick lanczos for quality, add an angle, and it won't rotate as expected. Use bicubic when you need both quality and rotation.
The other is edge fill. Rotate or move an image and something has to fill the gap. Left on edge, you get streaky smears; that's often fine for a subtle push-in and terrible for a big rotation. Switch to constant (with a constant_color that matches your scene) or reflect for a cleaner result. And if you're animating this across a batch, small per-frame changes look smooth while big jumps stutter - key your values gently and let the motion accumulate over frames.
Inputs (12)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| x | FLOAT | 0-4096–4096 | — |
| y | FLOAT | 0-4096–4096 | — |
| zoom | FLOAT | 1.00 | — |
| angle | FLOAT | 0-360–360 | — |
| shear | FLOAT | 0-4096–4096 | — |
| border_handling | COMBO | edge | 4 options: edge, constant, reflect, symmetric |
| constant_color | COLOR | #000000 | — |
| filter_typeopt | COMBO | bilinear | 6 options: nearest, box, bilinear, hamming, bicubic, lanczos |
| stretch_xopt | FLOAT | 1.000.001–10 | — |
| stretch_yopt | FLOAT | 1.000.001–10 | — |
| use_normalizedopt | BOOLEAN | false | If true, transform values are scaled to image dimensions. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |