YG Poster Layout Scanner
Auto-detect where the poster's profile photo and name badge go
- images
- images
- json_list
- output_dir
This is the most interesting node in the whole pack, and it solves a very specific problem. When you generate "devotional poster" style images with a model like Nano Banana, the model often draws a blank square where a profile photo should go and a wide strip where a name badge belongs. If you're compositing hundreds of those posters, you need to know where those panels are - in code. YG Poster Layout Scanner looks at each generated image, finds the profile-photo frame and the name badge, picks a clean spot for a watermark, and emits that whole layout as JSON. It never draws a single pixel - the image passes through untouched, and the JSON is your instruction sheet for compositing the text, photo, and watermark later.
How it works
Under the hood it's real image analysis, not AI magic. It shrinks the image, computes local variance to separate flat solid-fill areas from textured/detailed ones, and runs connected-component labeling to find contiguous flat panels. Candidate panels are then classified by aspect ratio and size: a square-ish panel of plausible area becomes the profile frame, a wide-and-short panel becomes the name badge. Shape is estimated from how full each bounding box is (square, rounded_rectangle, circle, ellipse, ornate_frame - the model apparently likes drawing ornate ones).
For the watermark it does a separate pass: it searches for the quietest free rectangle that doesn't overlap either panel, biasing toward image edges, using gradient energy to stay off the quote text. Everything is scaled into the canvas_width × canvas_height coordinate space you set, so the JSON is resolution-independent. The whole scan runs at a small working size (384px max dimension) specifically so it stays cheap across thousands of images.
Outputs and the JSON
images- the input batch, passed through untouched.json_list- a JSON array with one object per image:imagefilename,canvas, thequote(greeting + text, matched by position to your input lists), andprofile_photo,name_badge, andwatermarkblocks, each withx,y,width,height(plusshapeand adetectedflag). If a panel isn't found, it falls back to sensible defaults and marksdetected: false.output_dir- where files were written.
It also saves each image as poster_0001.png with a same-name poster_0001.json side by side in ComfyUI/output/yg_posters/<batch>/ (or your output_folder), and can package them into ZIP chunks via zip_chunk_size (250 per archive by default; 0 disables zipping). resize_to_canvas optionally saves the PNG at the exact canvas size.
The inputs you'll actually set
images- wire your poster generator's output.canvas_width/canvas_height- the coordinate space for the JSON (defaults 1080×1920). The tooltip notes you can change these any time; the JSON just re-scales.quotes/greetings- one per image, separated by a line containing---. These get matched by index into the JSON'squoteblock.name_prefix/start_index- naming for the saved pairs (poster_0001.png/poster_0001.json, ...).profile_min_area_pct/profile_max_area_pct- the size window a panel must fall in to count as a profile frame (defaults 2–22% of the image). If your model draws frames larger or smaller than that, tune these; it's the most likely adjustment you'll make.watermark_width/watermark_height/watermark_opacity- the watermark slot's desired size and the opacity to record in the JSON.
Installing it
It's part of comfyui_yg_nodes (MIT, "YG Custom Nodes" v1.0.4 by Mallikarjuna Rao Koliparthi). No required extra Python dependencies - it uses scipy if present for faster connected-component labeling, and falls back to a pure-Python two-pass algorithm if not, so it works either way. Install via ComfyUI Manager (search comfyui_yg_nodes) or:
cd ComfyUI/custom_nodes
git clone https://github.com/mallikarjunaraokoliparthi/comfyui_yg_nodes.git
Restart ComfyUI; it's under YG Custom Nodes.
Honest expectations
This is a heuristic scanner, not a vision model. If your posters are clean template-style generations, detection is reliable; if the model draws chaotic backgrounds, expect detected: false fallbacks on a chunk of images - the status line tells you how many used fallbacks, and that's your QA signal. The whole pipeline it was built for (generate → scan → composite in another tool using the JSON) is a genuinely slick batch workflow, and the JSON coordinate space makes it easy to drive an external compositor. Just don't assume it'll read a hand-drawn Photoshop file the way it reads a model's generated panels. For its intended lane, it's the most impressive node in this pack by a wide margin.
Inputs (16)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| canvas_width | INT | 108064–8192 | Coordinate space for the JSON. Change any time. |
| canvas_height | INT | 192064–8192 | — |
| name_prefix | STRING | poster | Image and JSON share this name: poster_0001.png / poster_0001.json |
| start_index | INT | 10–999999 | — |
| quotesopt | STRING | One quote per image, separated by a line containing --- | |
| greetingsopt | STRING | One greeting per image, separated by ---. Blank is fine. | |
| watermark_widthopt | INT | 1508–4096 | — |
| watermark_heightopt | INT | 1508–4096 | — |
| watermark_opacityopt | FLOAT | 0.180–1 | — |
| profile_min_area_pctopt | FLOAT | 2.00.1–50 | — |
| profile_max_area_pctopt | FLOAT | 22.01–90 | — |
| save_filesopt | BOOLEAN | true | — |
| resize_to_canvasopt | BOOLEAN | false | Save the PNG at canvas_width × canvas_height |
| zip_chunk_sizeopt | INT | 2500–5000 | Images per ZIP. 0 = do not zip. |
| output_folderopt | STRING | Blank = ComfyUI output/yg_posters/<batch> |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | — |
| json_list | STRING | — |
| output_dir | STRING | — |