Nodes/ComfyUI-BFSNodes/BFS Crop Size
ComfyUI Node

BFS Crop Size

BFSCropSize tells you the crop size before you build the latent

By alisson-anjos·Created 6 months ago·Updated 2 days ago· 109
BFS Crop Size
  • guide_video
  • subject_mask
  • width
  • height
  • crop_bboxes
  • info
crop_modetracked
crop_scale1.50
crop_divisible_by32

If you've run a crop-based face swap or subject edit on LTX video, you know the exact pain this node kills. The BFS sampler in this pack works out its crop box from your mask at run time, but ComfyUI's EmptyLTXVLatentVideo demands concrete width and height widgets before anything runs. So you guessed the numbers, hit queue, and the sampler silently resized your crop to fit the latent you built. Wrong framing, wasted minutes, repeat after every mask tweak. BFSCropSize runs the same planner early and hands you the exact numbers up front.

What it actually is

BFSCropSize is the planning half of the BFS sampler, exposed as a standalone node. It feeds it the same guide_video, the same subject_mask, and the same three crop widgets the sampler uses, runs the identical crop planner, and returns four outputs: width and height (wire them straight into EmptyLTXVLatentVideo), crop_bboxes (one box per frame, the ones the sampler will actually use - these feed BFS Paste Back if you run a second pass in crop space), and an info string describing what the planner decided, for a PreviewAny.

Why does this pack care about a stable crop at all? Same reason the still-image detailers in the KB do their crop-and-zoom dance: a face occupying eighty pixels of a frame has no latent budget, and no identity LoRA can carry it. You sample inside a box around the subject and paste it back. But video adds a trap - a naive per-frame crop jitters in position and size, and a video model reads that jitter as camera motion. So the BFS planner (vendored from drozbay's MaskVidExperiments, which is why this pack is GPL) plans boxes over the whole clip: they hold still through mask noise and occlusion and only chase sustained movement.

The inputs that matter

  • guide_video and subject_mask - literally the same clip and mask you feed the sampler. Not "a similar" mask. The same one.
  • crop_mode - combined plans one static box for the whole clip, tracked keeps a constant-size box that holds still until the subject would leave it, zoomed also lets the box follow the subject's size over the clip.
  • crop_scale - box size as a multiple of the subject; 1.5 (the default) leaves about a third as margin. The tooltip's warning is worth quoting back: keep neck and shoulders in, because a face-tight crop is a framing the model never saw in training.
  • crop_divisible_by - defaults to 32, which is exactly what LTX wants (LTX-2.3 dimensions must be multiples of 32). The crop gets rounded up to this grid.

Where people get burned

The mismatch. The planner is deterministic - equal inputs give the equal box - so everything stays consistent only if the three widgets on this node are identical to the sampler's. Change crop_scale to 2.0 on one and leave 1.5 on the other and nothing errors; the sampler just silently resizes its crop into a latent that wasn't built for it. The node cannot see that you diverged. When you're debugging a crop, change the widgets in both places, or copy one node and wire it twice.

One more honest note: crop_mode here has no off option, so this node is only meaningful when cropping is on. And it does run the actual crop to measure it, so it's not free - but it's image resizing, not diffusion. Nothing to sample, no VRAM fireworks.

Installing it

Same as any node in the BFS pack. ComfyUI Manager, search "ComfyUI-BFSNodes", install, restart. Or the manual route:

cd ComfyUI/custom_nodes
git clone https://github.com/alisson-anjos/ComfyUI-BFSNodes.git
cd ComfyUI-BFSNodes
pip install -r requirements.txt

Heads up on the dependency list: the pack's requirements.txt pulls insightface==0.7.3 and onnxruntime for its face-detection paths, and those are the ones that tend to fight an older portable Python. The crop planner itself only needs numpy/scipy/opencv (scipy arrives transitively via librosa), so a failed insightface build usually doesn't stop this node from loading - but ComfyUI will still refuse to import the whole pack if anything at the top errors. You also don't need any extra model downloads for BFSCropSize; the models live on the LTX side of the workflow.

One workflow caveat the source makes explicit: the sampler strongly wants the AV (video-plus-audio) latent that EmptyLTXVLatentVideo produces, so use that node for the empty latent and let this one fill in its size.

CategoryBFS/video

Inputs (5)

NameTypeDefaultDescription
guide_videoIMAGEThe same clip you feed the sampler.
subject_maskMASKThe same mask you feed the sampler.
crop_modeCOMBOtracked3 options: combined, tracked, zoomed
crop_scaleFLOAT1.501–4
crop_divisible_byINT328–128

Outputs (4)

NameTypeDescription
widthINTCrop width -- into EmptyLTXVLatentVideo's width.
heightINTCrop height -- into EmptyLTXVLatentVideo's height.
crop_bboxesBOUNDING_BOXOne box per frame, the same the sampler will use. Feeds BFS Paste Back.
infoSTRINGWhat the planner decided, for a PreviewAny.