Image Crop Edit
Crop and straighten photos without leaving your ComfyUI graph
- image
- cropped
- mask
If you've ever generated a nice 16:9 wallpaper and then realized the subject is three pixels off-center, you know the ComfyUI crop story: a CropImage node that takes four numbers, which means guessing coordinates, running it, looking, and guessing again. Image Crop Edit is the version you actually want - a Photoshop-style crop box rendered inside the node itself. You drag, scroll, and rotate on the live canvas; the math is worked out for you. It's a young, single-node pack from Luna-visual, and its whole pitch is that crop-and-reframe stops being a round trip through an external editor.
Where it earns its place: any reframing you'd otherwise export-and-reimport for - trimming an image to a trained aspect ratio before an img2img pass, cutting a face bigger for a detail pass, or straightening the horizon before you upscale. Those crop-upscale-detail loops are everywhere in the ecosystem, and a visual editor makes them painless instead of pain-by-coordinates.
How it works
Drop it into a graph and it's immediately a big canvas showing whatever is connected to image. That canvas is a browser-side editor: it lets you position a crop box, zoom the image underneath it (scroll), and rotate around a yellow anchor (double-click to place it, or drag the ruler at the bottom). Aspect presets - Original, 1:1, 4:3, 16:9, and friends - lock the box's ratio.
Here's the sneaky part: what you see is just a preview. The actual pixel crop happens only when the node runs. Every move you make is serialized into a hidden crop_data JSON widget (rotation, scale, pan, crop size, aspect), which is saved with the workflow - so your crop state survives a reload. At run time the Python side does a single PIL affine transform with bicubic resampling. And if you've set no crop at all, it detects the identity case and passes your image straight through untouched instead of needlessly resampling it.
The inputs and outputs that matter
Only three inputs exist, and you'll barely touch any of them:
image- what you're cropping. Anything that outputs an IMAGE.fill_color- the color for empty areas. Default#000000(black).crop_data- hidden internal JSON. Don't type in it; the editor writes it for you.
Outputs are cropped (the RGB result) and mask (the valid-area alpha, marking where real image pixels are versus fill). Wire cropped into your img2img/upscale/save chain; grab mask when you plan to composite the crop back onto something else.
Installing it
Via ComfyUI Manager, search Image Crop Edit (or ComfyUI-ImageCropEdit). Manual install is the usual two lines:
cd ComfyUI/custom_nodes
git clone https://github.com/Luna-visual/ComfyUI-ImageCropEdit
Then restart ComfyUI and hard-refresh the browser with Ctrl+F5 - the editor is custom front-end code, so a stale page won't show it. It's lightweight: the only Python dependency is Pillow (already present in basically every ComfyUI), no models, no API keys. Note the pack's license: free for use including commercial projects, but you may not resell the node itself or bundle it into a paid pack.
Where people get tripped up
- You resized upstream, but the editor still shows the old small image. The viewport shows the last executed image size. After a
Resizeor other processing node, press the play button on this node's toolbar (the same button Save Image uses) - that runs your upstream nodes and loads their output. - Rotated corners turned black. The crop box can't leave the canvas, but it can cover empty canvas after a rotation or zoom-out. Those pixels become
fill_color. If black corners bother you, givefill_coloran 8-digit hex with a00alpha (like#00000000) so those areas go transparent - and then themaskoutput becomes genuinely useful. Default opaque black fill means the mask is a wall of ones, so don't expect it to do anything until you set that. - The node seems to do nothing. If you never moved the box, it's an identity passthrough by design - crop something and it starts cropping.
This is a brand-new pack (early days, essentially no community chatter yet), so expect rough edges and report them on the GitHub issues tracker. But as a "fix my framing" tool it already beats fiddling with four numbers.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| fill_color | STRING | #000000 | — |
| crop_data | STRING | {} | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| cropped | IMAGE | — |
| mask | MASK | — |