小珠光 ATBC (智能裁剪)
The ComfyUI crop node that fixes framing for you
- image
- mask
- cropped_image
- crop_box
- cropped_mask
Most ComfyUI crop nodes make you type four numbers. 小珠光 ATBC ("智能裁剪", smart crop) does the thing you actually want: you feed it an image plus a mask, and it finds the mask's bounding box, crops that region, and resizes it to a target resolution while keeping the aspect ratio sensible. It's the "detect, crop, resize" step of the automatic-detailing loop that the Impact Pack popularized - except the detection is a mask you already have, so there's no YOLO model to download and no SEGS plumbing to learn.
Where it earns its keep: face-detail workflows where you mask a face and want a clean 1024-ish crop to re-render; video jobs where the subject drifts frame to frame and you want the crop box to stay put; and any upscale-then-paste-back pipeline where consistent framing matters. It also pairs perfectly with the pack's own ATR node, which pastes the processed crop back - ATBC outputs a crop_box (a CROPBOX) that ATR consumes directly, so the round-trip knows exactly where the crop came from.
How it works
ATBC takes the mask, computes its bounding box, and grows it by Box_grow_factor (1.0 = no growth, up to 5x). Then it resizes to the target megapixels (where 1024×1024 counts as one), snapped to the closest of the preset aspect ratios (auto, 1:1, 4:3, 3:4, 16:9, 9:16) and rounded so the result is divisible by divisible_by (default 8 - the standard for latent-friendly sizes). If the crop box hangs over the edge of the image, the overflow is filled with fill_color (hex or a color name) instead of crashing. All of it runs through numpy + OpenCV in one batched pass, so it's fast on video too.
Two settings exist purely for video. mask_smooth runs an exponential moving average on the crop box position across frames - raise it to stop a jumpy mask from producing a jittering crop. sum_mask unions all the frame masks into one box, so every frame in the batch comes out the same size. If your mask already covers most of the image, startup_threshold (0.4 default) detects that and skips the ratio/grow juggling entirely.
The inputs that matter
You only really touch a handful:
imageandmask- feed it any mask you have, including one from a SAM segmenter or the pack's own image loader.megapixels- your target output size. 1 is a good starting point for a detail crop.ratio- set it when you want a specific frame ratio (say 9:16 for a vertical crop) instead of letting it auto-pick.Box_grow_factor- the one to bump when the crop feels claustrophobic.
Outputs: cropped_image (IMAGE), crop_box (CROPBOX), and cropped_mask (MASK) so your downstream inpainting still has the mask that defines the region. Wire crop_box into ATR when you're pasting back.
Install
It ships in the ComfyUI-xiaozhuguang pack - ComfyUI Manager (search "ComfyUI-xiaozhuguang" or "小珠光"), or:
cd ComfyUI/custom_nodes/
git clone https://github.com/xiaozhuguang/ComfyUI-xiaozhuguang.git
Then restart ComfyUI. No models to download for this node; the pack's real dependencies (torch, numpy, Pillow, opencv-python) are all things ComfyUI already has. The only thing worth knowing: this pack is a big Chinese/English bilingual suite, so if the node shows up as "小珠光 ATBC" that's the same node.
Gotchas
The classic beginner trap here is forgetting that the crop box is resized, not just cropped - if you feed the output straight to an img2img node expecting the original pixel count, you'll get whatever megapixels says. And fill_color matters more than it looks: when the mask hugs the image edge, the pad is what keeps the crop from turning into a black sliver. Keep the CROPBOX wire intact and let ATR handle the geometry - that's the workflow this node was built for.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| mask | MASK | — | |
| resize_mode | COMBO | lanczos | 4 options: lanczos, nearest-exact, bilinear, bicubic |
| Box_grow_factoropt | FLOAT | 1.001–5 | 裁剪区域的扩展倍数,1.0表示不扩展,大于1.0表示按比例扩大 |
| megapixelsopt | FLOAT | 1.00.1–10 | 目标图像的百万像素数,以1024*1024为1百万像素基准 |
| divisible_byopt | INT | 81–1024 | 目标分辨率必须被此数字整除 |
| ratioopt | COMBO | auto | 裁剪比例模式,auto为自动检测最接近比例 |
| startup_thresholdopt | FLOAT | 0.400–1 | 当mask的box面积与输入图像的面积占比达到此阈值时,跳过ratio和box_grow_factor判断 |
| fill_coloropt | STRING | #FFFFFF | 边界超出时的填充颜色,支持hex格式(#FFFFFF/#FFF)或颜色名称(red/blue/green等) |
| mask_smoothopt | FLOAT | 0.000–0.98 | 遮罩时间平滑系数,0为不开启,越大越平滑(0-0.98)。对视频帧的裁剪框位置进行指数移动平均,减少画面抖动 |
| sum_maskopt | BOOLEAN | false | 开启后,将所有帧的遮罩求和(截断到0-1)后统一计算裁剪框,所有帧输出尺寸一致 |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| cropped_image | IMAGE | — |
| crop_box | CROPBOX | — |
| cropped_mask | MASK | — |