BK Image Rect Layout
Drops images into the black rectangles you drew
- background_image
- image_list
- IMAGE
- RECT_PREVIEW
- REMAINING_IMAGE_LIST
Where BK Image Random Layout scatters images along a drawn line, BK Image Rect Layout is the tidier cousin: you draw black rectangles on a white background, and it finds the bounding box of those dark regions, then picks an image from your list that fits the rectangle's shape and centers it inside. Poster frames, photo slots, comic panels - draw the frame, let the node fill it.
It's part of the ComfyUI_BaiKong_Node pack, the no-model designer toolkit for color and layout. Like its sibling, it's entirely CPU-side: opencv does the contour work, PIL does the fitting. Nothing to download beyond the pip deps.
How it works
The pipeline: background_image → grayscale → threshold at 128 with inversion (so your dark marks become the foreground) → cv2.findContours → a single bounding rectangle computed from all contours combined. Small noise contours under 10px area get filtered out. Then the node scans your image_list for the image whose aspect ratio is closest to the rectangle's, checks the fit is within aspect_ratio_threshold, scales that image to fit (LANCZOS, aspect preserved, centered), and composites it in.
Two things worth understanding from the source:
- It finds one bounding box around all black elements, not one box per element. If you draw two separate dark blobs, they get treated as the corners of a single larger rectangle. That's a feature if you're framing a single panel, and a gotcha if you expected per-blob placement.
- The fit logic is aspect-ratio matching, not "largest image wins." Images are ranked by how close their aspect ratio is to the rectangle's (with the threshold as a tolerance), so a tall portrait slot grabs a tall portrait. If nothing is close enough, the node either keeps the background as-is or leaves the slot empty depending on use_background_if_no_match.
The outputs are IMAGE (the composited result), RECT_PREVIEW (a debug overlay showing the found rectangle), and REMAINING_IMAGE_LIST - the input list minus the image it used. That third output is the clever bit: chain this node onto itself and you can fill several frames from one pool, each step consuming one image.
Inputs
- background_image - your white canvas with dark marks.
- image_list - the
IMAGE_LISTpool (build it with BK Image List). - aspect_ratio_threshold - how tolerant the aspect match is (0.01–0.5, default 0.25).
- use_background_if_no_match - on by default; if off, no match leaves the slot empty.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/JayLyu/ComfyUI_BaiKong_Node
cd ComfyUI_BaiKong_Node
pip install -r requirements.txt
Restart ComfyUI, or install "ComfyUI_BaiKong_Node" from ComfyUI Manager. Same CPU-only deps as the rest of the pack: scikit-learn, scipy, opencv-python, scikit-image, matplotlib.
Gotchas
The one-bounding-box behavior is the thing that'll surprise you - plan your background so all dark marks form a single intended frame, or split it into separate runs. And if nothing matches, remember the fallback is a toggle, not a given: with use_background_if_no_match off you get an empty slot with the rectangle still in the output. The RECT_PREVIEW output exists precisely so you can confirm the node found what you drew before you trust the result.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| background_image | IMAGE | — | |
| image_list | IMAGE_LIST | — | |
| aspect_ratio_thresholdopt | FLOAT | 0.250.01–0.5 | — |
| use_background_if_no_matchopt | BOOLEAN | true | — |
| random_selectopt | BOOLEAN | false | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |
| RECT_PREVIEW | IMAGE | — |
| REMAINING_IMAGE_LIST | IMAGE_LIST | — |