Nodes/msch-comfyui-nodes/marioslideshow - Subject Framer
ComfyUI Node

marioslideshow - Subject Framer

Stop the Ken Burns pan from cutting heads off

By mariobilly·Created a day ago·Updated a day ago· 0
marioslideshow - Subject Framer
  • photos
  • images
  • masks
  • focus
  • framing_preview
  • focus_json
mode
subject_margin0.20
focus_x0.50
focus_y0.50
overrides_json

Animated slideshows have a nasty habit: the camera pushes in, pans across, and crops the frame - and if it's cropping around the image center, it decapitates people. The "marioslideshow - Subject Framer" exists to stop that. For every photo in your collection it figures out where the subject actually is and hands the renderer a focus point plus a protected region, so the camera moves keep the subject in frame instead of through it.

Read the description on the tin again: "Compute framing guidance... Connect the same source photos to this node and the renderer." This node plans crops. It doesn't generate, upscale, or touch pixels - it outputs a plan (MARIO_FOCUS) that the Renderer consumes. It slots between Load Images and the Renderer, and it's worth having in every slideshow with people in it.

How it works

Three ways to say "here's the subject," chosen by mode:

  • Faces - runs a classical face detector on each photo. The nice part: it's the LBP frontal-face cascade that ships inside scikit-image (data.lbp_frontal_face_cascade_filename()), so there's no model download and it runs on CPU in milliseconds. The honest part: it detects frontal faces, not profiles, not dogs, not products. When nothing is found you get a center fallback, and the JSON will tell you it happened (each item records a method like faces, mask, manual, override or center fallback).
  • Manual - you supply normalized focus_x / focus_y (0 to 1) as the point of interest for every image.
  • masks (optional MASK socket) - one mask per source image, in matching order, where white (>0.5) means subject. The node takes the mask's bounding box as the protected region, and masks override face detection entirely.

subject_margin (default 0.2) expands the detected face or mask bounds to give the subject breathing room inside the crop. And when the detector or your masks get one wrong, overrides_json fixes individual images without re-running everything - zero-based per-image overrides like {"0": {"x": 0.8, "y": 0.3}}, or a full box {"box": [left, top, right, bottom]} in normalized coordinates. It's multiline and designed to be edited in the widget.

Outputs

  • focus (MARIO_FOCUS) - the payload; wire it into the Renderer's focus socket.
  • framing_preview (IMAGE) - a contact sheet with a green box around each protected region and a red cross at the focus point. Shows up to 12 images, but all of them get analyzed. This is your sanity check before committing to a long render.
  • focus_json (STRING) - the same plan as printable JSON, handy for eyeballing the method per image.

Installing it

Same pack install as the others:

cd ComfyUI/custom_nodes
git clone https://github.com/mariobilly/msch-slideshow.git
cd msch-slideshow
python -m pip install -r requirements.txt
python -m pip install -r requirements-advanced.txt

That second line matters: Faces mode lazily imports scikit-image when it runs, and skimage lives in requirements-advanced.txt, not the base file. If you skip it, you'll get an import error the first time you hit Faces. Base requirements (numpy, Pillow, imageio-ffmpeg, torch, av) come from the first file. Windows portable users substitute .\python_embeded\python.exe. And remember the README banner: this standalone repo is superseded by the unified MSCH Nodes pack - one install or the other, not both, or nodes register twice.

Where people get burned

Connect exactly one of photos or images - the node errors out if you feed both or neither. Face mode plus masks is fine (masks win), but the masks socket needs one mask per source image as [B, H, W], and each image in your slideshow can only be framed by so much. If a mask is inverted you'll frame the background - flip it so white is the subject.

The ordering rule is the real trap, and it's worth repeating because every MSCH node obeys it: framing items are indexed to the photo order you loaded. Wire the same Load Images output, in the same order, to both the Subject Framer and the Renderer. Change the photo collection between the two runs and your focus boxes drift onto the wrong pictures.

Finally, set expectations: Faces mode finds faces, not subjects in general. The pack's own guide is blunt - for products, side-profile portraits, or anything the detector misses, use masks or Manual mode. And "Smart fit" can still fall back to a contained crop when the protected region doesn't fit the scene's aspect ratio; this is framing guidance, not foreground segmentation, so it can't save a subject from a transition that sweeps across it.

Categorymarioslideshow/advanced

Inputs (8)

NameTypeDefaultDescription
modeCOMBO2 options: Faces, Manual
subject_marginFLOAT0.200–1
focus_xFLOAT0.500–1
focus_yFLOAT0.500–1
overrides_jsonSTRINGOptional zero-based image overrides, e.g. {"0": {"x": 0.8, "y": 0.3}}. Coordinates are normalized.
photosoptMARIO_IMAGES
imagesoptIMAGE
masksoptMASK

Outputs (3)

NameTypeDescription
focusMARIO_FOCUS
framing_previewIMAGE
focus_jsonSTRING