Imgutils Bbox Crop
Crop Every Detection Out of an Image, One by One
- image
- images
When you detect a face - or three, or twelve - the next question is always "now what?" Imgutils Bbox Crop is the answer that means "show me each one." It takes the source image plus a bounding-box JSON string (the json output from Imgutils Detect or OCR) and returns one cropped IMAGE per box, as a list.
Where it fits
This is the crop step in the detect → crop → re-render → paste loop that the KB's masking-detection doc calls the automation layer between manual inpainting and background removal. Detect finds the broken regions, this node isolates them, a re-render pass fixes each crop, and a paste step stitches them back. The typical imgutils-pack chain: Imgutils Detect → Imgutils Bbox Crop → an img2img/detail pass → composite.
How it works
The node parses the bbox JSON, and for each entry it clamps the box to the image bounds (so a detector that reports coordinates slightly off-canvas doesn't crash it), crops, and appends the result to a list. Two behaviors worth knowing: the output is a list (images, marked as a list in the schema), and if nothing parses - or no valid bbox is found - it falls back to returning the whole image rather than erroring. That fallback is nice for robustness and a trap if you assume it failed loudly.
The interface
image- the source to crop from.bboxes(STRING) - the JSON bbox array from Detect or OCR. Per the author's tooltip, each entry looks like{bbox: [x1,y1,x2,y2], ...}.- Output:
images(IMAGE list) - one cropped image per box.
Honest take
The list output is the thing to get comfortable with: the first crop gets previewed in the UI, and downstream list-aware nodes process the rest. If your downstream nodes expect a single image, this is where you learn that ComfyUI handles lists fine when the next node declares a list input - Bbox Crop's list is exactly what feeds per-crop processing. Compared to Impact Pack's one-node FaceDetailer (detect + refine + paste in a single node), this is the DIY path: more wiring, more control, and you can pick a different prompt or model per detected region, which the one-shot node can't.
One real gotcha: the crops are rectangles from a detector, so they include whatever surrounds the object. If you crop a face, expect background in the box. For clean subject isolation you'd pair this with a mask-based segmenter instead.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/xiaden/comfyui-imgutils.git
cd comfyui-imgutils
pip install -r requirements.txt
Or via ComfyUI Manager (search "imgutils"). Requires ComfyUI >= 0.25.0 and Python >= 3.10; pack dependency is dghs-imgutils[gpu]. This node itself is pure PIL cropping - no model downloads. (The Detect node feeding it will download its own detector on first use.)
Troubleshooting
If you get the whole image back instead of crops, the bboxes input isn't in the expected format - double-check you're wired to Detect's json output and not its human-readable detections string. And if crops look slightly offset, remember boxes are clamped to the canvas: a detection that reports coordinates beyond the image edge gets silently pinned, which reads as a shifted crop.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | Source image for cropping. | |
| bboxes | STRING | JSON bbox array from Detect or OCR node. Each entry: {bbox: [x1,y1,x2,y2], ...}. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | — |