Nodes/PortraitUtils/Crop Prompt from Config
ComfyUI Node

Crop Prompt from Config

The one-wire adapter for your segmentation node

By heyburns·Created about a year ago·Updated 23 days ago· 3
Crop Prompt from Config
  • crop_config
  • subject_mask

What it's for

Your subject mask prompt is sitting inside an Input & Crop Config bundle. Your segmenter - SAM 3, Grounded SAM, whatever you're using for promptable masking - wants a plain STRING. Typed bundles don't connect to primitive sockets, and that's deliberate: the whole point of the bundle is that configuration travels as one object, not as fifteen wires.

So this node is the adapter. One bundle in, one subject_mask string out. Nothing to configure, no widgets, no state. It's about as close to a no-op as a node gets, and it's the difference between "this config system works" and "I'm maintaining two copies of every prompt."

How it works

Required input: crop_config (PORTRAIT_CROP_CONFIG_V2). Output: subject_mask (STRING).

It reads the field and returns it. It does not rerun preparation, recrop, or validate that your prompt is a good one - the suite's own framing is that readers "expose existing values; they do not rerun preparation." If you change the prompt in the config node, the next execution picks it up.

Where it fits

The reason this exists is the mask stage, and specifically the fact that promptable segmentation lets you name a region instead of training a detector for it. SAM 3 takes a text phrase; GroundingDINO + SAM takes a phrase and returns a precise mask. Both want a string, and an editable prompt in your config is exactly the thing you want to change per project without redoing the graph.

Input & Crop Config ── crop_config ──> Crop Prompt from Config ── STRING ──> segmenter (subject mask)
                                                                                │
                                                                                v
                                                                      Smart Photo Prepare (mask)

That wiring is the pack's documented shape: the subject prompt drives the segmenter, the segmenter produces a mask, and Smart Photo Prepare uses that mask to place its crop. Change the prompt from person to the dog and the framing follows.

Two practical notes. Put the reader next to the segmenter, not next to the config - the whole reason for a reader instead of a direct wire is that a short local hop is easier to read than a wire crossing the canvas. And remember this emits exactly one string: the subject_mask field. If your workflow also needs a second, different prompt - the pack's own example uses a separate SAM 3 node prompted with head for the protected-region mask - that prompt lives in its own text source, because the crop config only carries the one. That second prompt doesn't come out of the crop config - there's only the one field to read.

The same pattern covers the rest of the suite, and it's worth knowing the family so you grab the right one instead of a generic converter:

  • Edit Prompt from Config - pulls the inpaint prompt or one of the three stitch prompts out of the edit bundle.
  • Outpaint Prompt from Config - the outpainting prompt as a STRING.
  • Seed from Config - the run seed as an INT, for a sampler.
  • Scale from Config - initial_upscale or final_upscale as a FLOAT, for a third-party upscaler.
  • Save Info from Source - filename and output directory out of the loader's source bundle.

Everything on that list is one input, one output, zero decisions.

Where people get burned

The only real failure mode is trying to skip it. Converting the segmenter's prompt widget to an input and wiring the config bundle into it won't work - the socket is STRING, the bundle is PORTRAIT_CROP_CONFIG_V2, and ComfyUI will refuse the connection. Same story if you try to feed the bundle into a PrimitiveString; the primitives are for primitives.

And if the reader errors with a type complaint, you've got a version mismatch, not a wiring mistake: an old 1.x config object (or a saved workflow carrying a retired AutoCrop Config node) is not a PORTRAIT_CROP_CONFIG_V2. Rebuild the config node and reconnect.

Install

Part of the PortraitUtils pack. ComfyUI Manager → search PortraitUtils (publisher heyburns, GPLv3), or:

cd ComfyUI/custom_nodes
git clone https://github.com/heyburns/PortraitUtils
/path/to/ComfyUI/venv/bin/python -m pip install -r PortraitUtils/requirements.txt

Install into ComfyUI's Python environment - numpy, Pillow, opencv-python-headless and tifffile, with only one OpenCV variant present - then restart the ComfyUI server. A browser refresh alone won't load new node classes, which is why "I installed it and there's no such node" is usually a restart problem.

CategoryPortraitUtils/Config V2/Readers

Inputs (1)

NameTypeDefaultDescription
crop_configPORTRAIT_CROP_CONFIG_V2—

Outputs (1)

NameTypeDescription
subject_maskSTRING—