Free Drag Crop (Interactive)
Stop typing crop pixels — drag the box instead
- image
- mask
- IMAGE
- MASK
- CROP_JSON
The crop node that finally feels like an editor
Cropping in ComfyUI has always been the annoying kind of precise. You stare at an image, type 128 into one INT widget, guess again at the next, run the queue, and discover the box was six pixels too far right. Repeat. Free Drag Crop is the fix: it puts an 8-handle selection box directly on the image preview, and you drag it like you would in Photoshop. No guessing, no run-wait-look loop.
The wider workflow is the real reason to care. The classic region-refinement trick - crop a face or an eye, render that tiny region at the model's full native resolution, paste it back - lives and dies on getting the box right the first time. Give a 64px eye a 1024px generation budget and the result is dramatically better than whole-frame editing; miss the box and you've cropped a forehead. It's also the fastest way to hit a target aspect ratio before sampling, whether that's 9:16 for vertical video or 21:9 for an ultrawide. People have long complained ComfyUI is a hostile place to do this kind of work, and this node is a genuine, low-friction answer.
How it works
It's a frontend-heavy node: a chunk of JavaScript draws the overlay, and a thin Python backend does the actual slicing. When the node runs, it takes your IMAGE, cuts it with image[:, top:bottom, left:right, :], and saves a downscaled preview (capped at 1024px) plus the original dimensions into ComfyUI's temp output. The JS reads that and draws your drag handles scaled to fit - but all the math stays in original pixel coordinates, not preview coordinates.
That's the "Resolution Stability Guard" the README brags about, demystified. The pixel math is just integer slicing, exact by construction - there's no rounding to drift. The real trick is that the overlay does its bookkeeping in real pixels so the selection doesn't shift as the preview scales. So yes, it stays sub-pixel accurate on big images, but the honest framing is "the math is trivial; not losing coordinates to the preview is the hard part."
The inputs that matter
The four you'll actually touch, unless you're feeling nostalgic for widgets:
- image (required) - what you're cropping. Everything else is driven by dragging.
- ratio_lock and aspect_ratio - the ones that will bite you. Ratio lock defaults to on at 16:9, so your first "freehand" drag will stubbornly stick to a widescreen box. Flip the lock off (or set
1:1/ a preset) before you drag freely. - mask (optional) - if you feed one in, it gets cropped in lockstep with the image and comes out the same size. Feed nothing, and you still get a full-white mask out. That alignment is exactly what masked inpaint workflows need: crop image and mask together, wire both into your sampler, composite back, and the unmasked pixels stay bit-identical.
The numeric crop_left / crop_right / crop_top / crop_bottom widgets and the crop_current_width / crop_current_height / crop_center_x / crop_center_y bookkeeping fields are there for serialization and manual nudging - the drag updates them live.
Outputs
Three sockets: IMAGE (the crop), MASK (cropped mask, or a white one if you gave none), and CROP_JSON - a JSON string with x, y, width, height, and the original dimensions, handy if a downstream node wants the box coordinates. It's a custom type, so it only plugs into wildcard inputs; most workflows will just use IMAGE and MASK.
Install
Zero friction here. ComfyUI Manager → search ComfyUI-free-drag-crop, or:
cd ComfyUI/custom_nodes/
git clone https://github.com/laolaoruqin/ComfyUI-free-drag-crop.git
Then restart ComfyUI. There's no requirements.txt and no model to download - it only uses torch, numpy, and PIL, all of which ComfyUI already ships. That alone puts it ahead of half the crop nodes out there.
Where people get burned
- No overlay until you run it once. The preview is generated at execution time, so a freshly-added node is blank until you hit Queue. Run it with the defaults, then drag.
- Ratio lock surprises (see above). Default 16:9 lock is the #1 "why won't it move" complaint.
- The selection starts at 512×512 until the image loads - don't judge the crop before the preview renders.
- Honest caveat: this is a young, single-node pack with almost no community footprint yet. The core mechanism is simple enough to trust, but it hasn't been battle-tested by thousands of workflows. If it misbehaves, the GitHub issue tracker is your only help desk.
If you crop more than once a week, the drag-to-select alone is worth the two minutes this takes to install.
Inputs (12)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| crop_left | INT | 00–8192 | — |
| crop_right | INT | 00–8192 | — |
| crop_top | INT | 00–8192 | — |
| crop_bottom | INT | 00–8192 | — |
| crop_current_widthopt | INT | 5120–16384 | — |
| crop_current_heightopt | INT | 5120–16384 | — |
| crop_center_xopt | INT | 2560–16384 | — |
| crop_center_yopt | INT | 2560–16384 | — |
| aspect_ratioopt | STRING | 16:9 | — |
| ratio_lockopt | BOOLEAN | true | — |
| maskopt | MASK | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |
| MASK | MASK | — |
| CROP_JSON | CROP_JSON | — |