Rotate Image (Any Angle)
Rotate Any Image Without Cropping, Shrinking, or Killing Your Transparency
- image
- mask
- image
- mask
Base ComfyUI is great at flipping an image and useless at rotating one. There's no stock "rotate by 17 degrees" that keeps your canvas the same size - so you either rotate and watch the corners get chopped or the canvas shrink, or you rotate a transparent PNG and get a black box back. Rotate Image (Any Angle) is a tiny, zero-dependency node that fixes all three of those at once: it rotates an RGB or RGBA image by any angle while preserving the canvas size, the dtype, the device, and optionally the transparency.
The niche is small but it comes up more than you'd think. Straightening a slightly crooked generation before you run it through a detailer or inpainting pass, rotating a batch of product shots to one consistent frame, fixing a scanned logo, compositing a sticker with real alpha - all of these need "arbitrary angle, keep everything else intact." People on the subreddit work around the gap by stringing Image Batch to List → Rotate → Image List to Batch together; this node handles whole batches natively, so you can skip the plumbing.
How it works
The mechanism is boring in the best way. It's pure PyTorch - no pip dependencies, no models, nothing to download. It builds an affine transform for your angle and resamples with F.affine_grid + F.grid_sample (bilinear). The canvas never changes: the output tensor keeps the exact same [batch, height, width, channels] shape as the input. Instead of resizing the canvas, it scales the image inside it according to your size mode.
Two details worth knowing from the source: a zero angle returns your image bit-for-bit unchanged (the test suite asserts torch.equal), and it runs entirely in memory on whatever device and dtype your image already lives on - no detours through numpy or PIL.
The inputs that matter
Only a few of the six inputs will ever be touched:
- angle - degrees, -360 to 360. That's it.
- size_mode - the one to actually learn.
original(default) rotates at 1:1 and clips whatever overflows the canvas.containshrinks the image until the whole rotated result fits inside, letterboxed with the background color.coverdoes the opposite - enlarges until it fills the canvas, cropping the overflow.match_short_edgeandmatch_long_edgeare niche variants for matching bounding-box edges. - background_mode -
white(default),black,custom, ortransparent. - custom_color - a hex string like
#FF00AA(3-digit hex works too). - mask (optional) - a ComfyUI mask. Note the convention: in this node, 1 is transparent, 0 is opaque. That's inverted from how most ComfyUI masks read, but it's deliberate: RGBA alpha and a connected mask are combined, and the mask output is built to plug straight into
Join Image with Alpha.
The transparency path is where this node earns its keep. With transparent background, connect both the image and mask outputs to ComfyUI's built-in Join Image with Alpha to preview or save as RGBA - a plain preview will otherwise show your transparency as black. The white, black, and custom modes composite the fill and emit a fully opaque mask, so if you're going opaque, wire the image output onward and ignore the mask entirely.
Installing it
Two options, both painless:
# ComfyUI Manager: search "Rotate Image (Any Angle)" and install
# or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/palealloy2999-prog/comfyUI-rotate-image.git
Then restart ComfyUI. There's no requirements.txt and the pyproject.toml declares zero dependencies - this is as close to a "safe, can't break anything" custom node as the ecosystem gets, which is refreshing given how many installs drag in heavy deps.
Gotchas
- Old workflows break. Workflows saved before the Registry-ready release reference the old internal ID
RotateImageNode; after upgrading, replace that node with the currentImageRotateAnyAngle_PaleAlloy. - Corners clipping is not a bug. In
originalmode a 45° rotation obviously overflows the canvas. If that surprises you, switch tocontain. - "Where's my transparency?" is the #1 confusion, and the answer is always Join Image with Alpha. ComfyUI's IMAGE tensor path doesn't carry RGBA the way you expect; the node gives you image + mask separately and lets ComfyUI's own node do the join.
- Exact 90° flips. It resamples with bilinear, so a lossless quarter-turn is still better done with a transpose node. Reach for this when the angle is arbitrary.
For what it is - a focused utility that does one geometric thing correctly, with tests, no deps, and a Japanese README to boot - it's the node you'd reach for. Rotate, straighten, and move on.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| angle | FLOAT | 0-360–360 | — |
| size_mode | COMBO | original | 5 options: cover, original, contain, match_short_edge, match_long_edge |
| background_mode | COMBO | white | 4 options: transparent, white, black, custom |
| custom_color | STRING | #FFFFFF | — |
| maskopt | MASK | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| mask | MASK | — |