图像裁剪丨像素
Shave exact pixels off each edge — and keep the mask
- image
- image
- range_mask
- crop_info
This is the crop node for the "just take 8 pixels off every edge" job - the one that crops a video frame's letterbox, strips a border, or trims a watermark margin. ImageCropByPixels removes a fixed pixel count from each side of an image, which sounds like the most boring thing in the world until you realize the stock ComfyUI crop can't do "remove N from each side" in one step at all.
It's from ComfyUI-QING (display name "图像裁剪丨像素"), a Chinese-authored utility pack with 79 nodes. Like its siblings ImageCropByPercent and ImageCropByOrigin, it returns a range_mask alongside the crop - a detail that punches well above its weight.
How it works
Four required inputs - left, top, right, bottom - each a string holding a pixel amount, like "300" or "80". The node cuts that many pixels off the corresponding edge: x_min = left, x_max = width - right, y_min = top, y_max = height - bottom. It clamps everything to the image bounds, so a larger-than-image value just collapses to the edge rather than erroring.
One quirk worth knowing: these four fields are typed as strings, not integers. The parser pulls the first number out of whatever you type, so "300" and even " 300 px" both work. It's a deliberate tolerance - you can wire in computed values from other nodes without a type conversion - but don't be surprised when the widget doesn't behave like a normal INT spinner. The sibling percent node uses proper FLOATs; this one is the string-typed member of the family.
The outputs that matter
image- the cropped tensor.range_mask- a MASK at source resolution, white where the crop box is. The reason to care: wire this into an inpaint pass and the sampler knows exactly what region it's supposed to be working in.crop_info- a STRING withcrop_box=...,size=..., andsource_size=.... Read it when a crop isn't what you expected.
When this beats the alternatives
Pixel crops are the resolution-sensitive member of the family. If you want the same visual framing across a batch of mixed sizes, use ImageCropByPercent. If you want the exact same physical margin - 10 pixels off every edge of every frame, regardless of how big the frame is - that's this node. Classic uses: stripping video letterbox bars, trimming a watermark/burn-in edge, or cropping a uniform border off a tiled output before stitching.
It also pairs with the range_mask output in a way that's easy to underuse: batch-to-batch region consistency. Same mask geometry across a whole folder means every downstream inpaint runs over the identical region, which keeps a detail pass stable.
Installing
Part of ComfyUI-QING - install the pack, get the node. ComfyUI Manager: search "ComfyUI-QING". Or by hand:
cd ComfyUI/custom_nodes
git clone https://github.com/GAO-SHIQING/ComfyUI-QING
cd ComfyUI-QING
python install_dependencies.py # or: pip install -r requirements.txt
Restart ComfyUI. Pure pip dependencies (Pillow, opencv-python, scipy, scikit-image, cairosvg), no models to download. China users: python install_dependencies.py --mirror --auto. Python ≥ 3.9 and a current ComfyUI.
Gotchas
If left+right (or top+bottom) exceeds the image width (height), you get a degenerate box: the node returns the original image unchanged with 裁剪失败 in crop_info - no error raised, just silently uncropped output. Check crop_info first whenever a crop looks like it didn't happen. And since the fields are strings, a genuinely empty value ("") also fails the parse and throws into the console, so leave the defaults ("0") in place.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| left | STRING | 0 | 左侧裁剪像素,如 300 |
| top | STRING | 0 | 上侧裁剪像素,如 120 |
| right | STRING | 0 | 右侧裁剪像素,如 200 |
| bottom | STRING | 0 | 下侧裁剪像素,如 80 |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| range_mask | MASK | — |
| crop_info | STRING | — |