裁剪图像🐠meeeyo.com
Crop an image and its mask in lockstep, so inpainting never misaligns
- image
- mask
- image
- mask
- width
- height
CustomCrop from MeeeyoAI/ComfyUI_StringOps is the node you reach for when you need an image and its mask resized to a standard resolution with the mask staying perfectly aligned to the pixels it describes. Plenty of tools will resize an image. Far fewer resize the mask through the identical transform at the same time - and that's exactly what inpaint workflows need, because a mask that drifted a few pixels off is an inpaint that edits the wrong part of the face.
The inputs
- image - an IMAGE tensor.
- mask - a MASK tensor. Required, not optional, per the schema - so you always need one, even if you only care about the image.
- width and height - target dimensions as integers, defaulting to 768x768, range 0–4096 with a step of 8. The step exists to nudge you toward latent-friendly dimensions; fighting it is a bad idea.
The outputs
Four of them, which is generous for a crop node:
- image and mask - the resized pair.
- width and height - the target dimensions echoed back as INTs, so you can feed them to an Empty Latent Image without re-typing them.
How it works
The node converts both tensors to PIL images, transposes EXIF orientation (so phone photos get righted before they're cropped), converts paletted/RGBA sources to a safe RGB, then runs ImageOps.fit on both with the same centering - a center-crop-and-resize to your target box, using BILINEAR resampling. Because the identical geometric transform is applied to image and mask together, the two stay aligned pixel-for-pixel. The mask is forced to grayscale on the way through, which is the right call for an inpaint mask.
Where people get burned: a mask doesn't have to be a separate painted thing. If you only want the image cropped, feed a full-white mask - it survives the transform fine and the crop still works. And remember the step of 8: feeding 1000x1000 is allowed but means a resize to a non-multiple-of-8 box, which downstream latent ops will grumble about. 1024 or 768 are the sane targets.
Wiring it
Crop the pair, then send image+mask into an inpaint model (or into the pack's ImageAdjuster for further work), and use the echoed width/height to size your Empty Latent Image to match. It's one of the few image nodes in an otherwise text-heavy pack, and it does the one thing that's fiddly to do by hand.
Installing
Standard pack install - Manager, search ComfyUI_StringOps, or:
cd ComfyUI/custom_nodes
git clone https://github.com/MeeeyoAI/ComfyUI_StringOps.git
Restart ComfyUI and look under "Meeeyo/File". The pack's dependencies (numpy, torch, Pillow) are already present in any working ComfyUI, so there's nothing extra to pull. No models, no downloads.
It's not the fanciest crop node in the ecosystem, and it demands a mask even for image-only jobs. But for the specific case of "crop this image and its mask to match, exactly," it does the job without a four-node detour.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| mask | MASK | — | |
| width | INT | 7680–4096 | — |
| height | INT | 7680–4096 | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| mask | MASK | — |
| width | INT | — |
| height | INT | — |