Nodes/comfyui_AcademiaSD/AcademiaSD MOSS Layout ๐Ÿ—บ๏ธ
ComfyUI Node

AcademiaSD MOSS Layout ๐Ÿ—บ๏ธ

Draw the boxes instead of writing 'headline top left' and hoping

By AcademiaSDยทCreated about a year agoยทUpdated about 16 hours agoยท 88
AcademiaSD MOSS Layout ๐Ÿ—บ๏ธ
  • clip
  • image
  • vlm
  • positive
  • negative
  • prompt
โ—„width1024โ–บ
โ—„height1024โ–บ
โ—„negative_promptโ–บ
โ—„layout_data{}โ–บ

Some prompts are a description; a poster is a spec. This headline here, the price bottom-left, two people in the lower third, the logo in the corner. MOSS-Image takes that as a JSON layout block, and the documented way to author it is to type coordinates in by hand, like a maniac. MOSS Layout gives you a canvas. You drag boxes, it writes the JSON.

What it's for

MOSS-Image is a model you reach for when the picture has to contain words that come out right - the same appetite that made glyph rendering the headline feature of Qwen-Image (kg/entities/qwen-image.json). A normal prompt says what the image looks like; a layout prompt says where each thing sits, and its text boxes carry the exact wording to render. Covers, posters, menus, infographics - anything with a grid and a title - live or die on that. This node is the editor for it, sitting beside the Prompt Enhancer, whose Moss (Design) preset writes prose about a poster. This one places the poster.

How the mechanism works

One widget is off-limits: layout_data. The editor's JavaScript keeps its whole state in there, and every box is stored as a fraction of the canvas, 0 to 1. That's why going from 1024 to 1536 doesn't scramble your layout - nothing is pixels until you hit queue.

On each run the fractions become pixels for the real width and height, get flipped into the centred yxyx form the model wants, and compiled into {"summary": โ€ฆ, "items": [โ€ฆ], "bbox_coord_space": "abs_centralized", "bbox_format": "yxyx"}. The sent string is one line with no spaces on purpose - that dense form is what the official pipeline feeds the model - while the panel shows it indented for humans. The compiler ports OpenMOSS's own compile_prompt.py, so it isn't one person's guess at the format.

A few details change what you see. A box with no description still goes in, with a generic caption - its position already said something. A text box with an empty text field is dropped, with a console line saying which one. And with no valid boxes at all, the node skips the layout entirely and hands the model your plain scene caption.

Inputs and outputs that matter

clip is the MOSS-Image text encoder and both conditionings are encoded with it, so wire the CLIP you already loaded for the model. width/height are the canvas, and the editor's proportions follow them - feed them from Resolution Calc if you use it. negative_prompt is a plain negative with no boxes; the tooltip says MOSS-Image is fine with it empty, and empty is where you start.

image and vlm are optional convenience. image is a background reference only: it sits behind your boxes so you can trace over a product shot. It never reaches the model. vlm powers the Analyze Image button.

Out come positive and negative (CONDITIONING, straight to the sampler) and prompt, the JSON string. You mostly won't wire prompt anywhere: Auto send is on by default, and every change rebuilds the JSON and writes it into the pack's own Positive node, negative into the Negative one - text in an editable box instead of a locked one.

Install

ComfyUI Manager โ†’ Install Custom Nodes โ†’ search AcademiaSD (published to the Comfy Registry as comfyui_AcademiaSD). Or:

cd ComfyUI/custom_nodes
git clone https://github.com/AcademiaSD/comfyui_AcademiaSD

Restart, and it's under Academia SD/MOSS-Image. No requirements file, no install script - everything it imports (numpy, Pillow, aiohttp) ships with ComfyUI, so there's nothing to pip install.

The model side is on you. Grab AcademiaSD_moss-image_v12.json from the repo's example_workflows/ for a working stack: a UNET loader on MOSS-Image, a Flux 2 VAE, and a CLIP loader of type moss_image on a Qwen3-VL - MOSS-Image's text tower is a Qwen3-VL, the same kind of CLIP the Prompt Enhancer wants.

Where people get burned

Analyze Image needs both wires. No image or no vlm and it says so on the node. It analyses the background, so connect one even if you only want boxes.

Box precision is the encoder's problem. The author's own warning: 8B places boxes far more accurately than 4B, and abliterated or heavily quantized builds lose precision. Boxes hovering near the right thing are a VLM choice, not a bug here.

Text boxes render what you typed. Line breaks are kept, so break the line where you want it. "SALE 50% OFF" across two lines is two lines; "big sale text" is nothing.

Auto send is on by default. Turn it off if you want to hand-edit the JSON, and then the panel is used exactly as-is - including not applying your box positions. Pick a mode and stay in it.

Saved layouts go to custom_nodes/comfyui_AcademiaSD/moss_layouts/, beside a current.json the editor overwrites with your last state - which is why a new node opens where you left off instead of empty.

CategoryAcademia SD/MOSS-Image

Inputs (7)

NameTypeDefaultDescription
clipCLIPโ€”
widthINT102416โ€“16384โ€”
heightINT102416โ€“16384โ€”
negative_promptSTRINGPlain negative prompt (no boxes). MOSS-Image works fine with it empty.
layout_dataSTRING{}โ€”
imageoptIMAGEBackground reference shown behind the boxes. Only for placing them: it does not reach the model.
vlmoptCLIPOptional Qwen3-VL text encoder (as in the Prompt Enhancer) for the Analyze Image button, which places boxes from the image.

Outputs (3)

NameTypeDescription
positiveCONDITIONINGโ€”
negativeCONDITIONINGโ€”
promptSTRINGโ€”