Nodes/ComfyUI-FeiFei/Cinematic Frame & Subtitle
ComfyUI Node

Cinematic Frame & Subtitle

Turn a render into a movie still

By aifeifei798·Created about a month ago·Updated about 12 hours ago· 3
Cinematic Frame & Subtitle
  • image
  • image
◄aspect_ratio21:9►
◄lock_modeShort Side (recommended)►
◄base_side1024►
◄fill_modeCinematic Crop (fill frame)►
◄subtitle_topWe were all waiting for someone who was never coming.►
◄subtitle_bottom►
◄subtitle_size0.045►
◄subtitle_colorYellow►
◄shadow0.80►
◄positionBottom►
◄timecode►
◄font_path►

Your model gives you a square or a 16:9 frame. What you want is the other thing - a still that looks like a frame grab from a 2.39:1 print with a yellow subtitle sitting on it. You can do that in Photoshop, or you can do it in the graph, deterministically, in about a fifth of a second, and keep the whole pipeline in ComfyUI. That's the job this node does.

It's the last creative step before you save. Cropping and typesetting aren't diffusion work - no model runs here, it's PIL and torch - which is exactly why you should do it in the graph instead of re-generating at some odd resolution and hoping the crop lands well.

How the frame gets chosen

aspect_ratio and lock_mode are deliberately identical to the pack's Aspect Ratio (1024) node, because the sizing math is literally the same calc_size() function imported from the same file. Same ratio list, same rule. So one ratio can drive both nodes and the frames come out pixel-identical - and if you feed this node the aspect_ratio string from Prompt Director (convert the widget to an input first), it's already legal, since that string is clamped to this exact list upstream.

lock_mode picks which side base_side pins. Short Side (recommended) is what you want 95% of the time: 21:9 stays 1024 high, 9:16 stays 1024 wide, so a scope frame and a vertical reel cost the same compute. At base_side 1024 that gives you 21:9 → 2384×1024, 16:9 → 1824×1024, 9:16 → 1024×1824. Both dimensions are always multiples of 16. Custom ratios work too - punch in 2.39:1 and you get 2448×1024.

Then fill_mode decides how your picture reaches that frame:

  • Cinematic Crop (fill frame) - the default. Scales to fill and cuts the overflow off the centre. A 16:9 render dropped into 21:9 loses its top and bottom, never gains side bars. If your subject is centred this is invisible; if it isn't, check the result before you commit.
  • Letterbox (black bars) - the only mode that shows the whole image, adding bars on whichever axis is left over.

The subtitle part

subtitle_top is set first and largest; subtitle_bottom sits under it at 82% of that size and is skipped entirely when empty. subtitle_size is a fraction of the frame's short side (0.045 default, ≈46px), which is why the line keeps the same optical weight in 21:9 and 9:16 instead of ballooning on a portrait frame. Long lines wrap at 86% of the picture width, per word for Latin and per character for CJK. subtitle_color gives you Yellow, White or Amber, and shadow (0.8 default) is a soft drop shadow scaled to the type, so the line survives a bright sky.

The optional group is where the polish lives. position = Bottom centres the line inside the lower black bar when Letterbox left room for one, and otherwise sits it just above the bottom edge of the picture; Center is the title-card placement. timecode takes 01:23:45:12 and burns a dashed box into the top-right with a TC prefix added for you - leave it empty and nothing is drawn. font_path empty falls back to DejaVu/Arial for Latin and Noto CJK/YaHei/PingFang when the line actually contains CJK characters.

One output: image. Wire it into your SaveImage, or into the pack's Watermark node.

Order matters, and the README is explicit about it: after the upscale, after Film Grain, before the watermark. Crop first so the subtitle lands inside the finished frame; watermark last so it sits on top rather than being cropped off the bottom edge.

Install

Search ComfyUI-FeiFei in ComfyUI Manager, or:

cd ComfyUI/custom_nodes
git clone https://github.com/aifeifei798/ComfyUI-FeiFei.git
# restart ComfyUI, nodes show up under the FeiFei category

No model downloads, no heavy dependencies. The pack's requirements.txt lists numpy, Pillow and openai>=1.40, and only the LLM nodes ever touch the last one. The repo also ships an example workflow at Workflow/ComfyUI-FeiFei.json - drag it onto the canvas and this node is already wired between the RTX upscale and the watermark at 2:1, Cinematic Crop, two English lines in Yellow.

Where people get burned

  • Tofu boxes instead of Chinese/Japanese text. A missing font, not a node bug. Point font_path at a real CJK file, e.g. /usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc.
  • Heads getting cut. Cinematic Crop takes from the centre. Confirm the crop at your ratio, or switch to Letterbox and accept bars.
  • The subtitle is baked in. It's pixels now - no layer, no undo. Duplicate the node with subtitle_top empty if you want a clean version of the same frame in the same run.
  • The node isn't in the menu. Every node in this pack is imported inside its own try/except, so one bad node doesn't take the pack down. If everything else is there and this isn't, grep your console for [FeiFei] CinematicFrameSubtitle failed to load - the traceback is right under it.

For a batch of unrelated stills, skip this node. It's for the workflow where you're deliberately building a shot and every frame should match.

CategoryFeiFei

Inputs (13)

NameTypeDefaultDescription
imageIMAGE—
aspect_ratioCOMBO21:9Aspect of the finished still. Same list as the Aspect Ratio (1024) node, so one ratio can drive both. 21:9 is the scope look, 16:9 the clean HD frame, 9:16 and 9:21 the vertical ones.
lock_modeCOMBOShort Side (recommended)Which side base_side pins. Same rule as the Aspect Ratio (1024) node: Short Side keeps 21:9 at 1024 high and 9:16 at 1024 wide.
base_sideINT1024128–4096The side pinned by lock_mode; the other side follows the ratio. A 21:9 still at 1024 comes out 2384x1024. Always a multiple of 16.
fill_modeCOMBOCinematic Crop (fill frame)How the picture reaches the frame. Cinematic Crop (the default) scales the image to fill the frame and cuts the overflow off the top/bottom or the sides, so the frame is always completely covered - a 16:9 render in 21:9 loses its top and bottom, never gains side bars. Letterbox is the exception: it shows the whole image and adds black bars on the leftover axis.
subtitle_topSTRINGWe were all waiting for someone who was never coming.Main subtitle line, typeset first and largest. Any language; long lines wrap to 86% of the picture width.
subtitle_bottomSTRINGSecond line, set under the main one at 82% of its size. Leave it empty for a single-line subtitle.
subtitle_sizeFLOAT0.0450.015–0.12Main line height as a fraction of the frame's short side, so the subtitle keeps the same optical size in 21:9 and in 9:16. 0.045 is about 46px on a 1024px-short-side frame.
subtitle_colorCOMBOYellowYellow is the usual hard-subtitle look, White the plain theatrical one.
shadowFLOAT0.800–1Soft drop shadow under the glyphs, scaled to the font size, so the line stays readable over a bright frame. 0 turns it off.
positionoptCOMBOBottomBottom centres the line in the lower black bar when Letterbox leaves room for it, and otherwise sets it just above the bottom edge of the picture. Center is the title-card placement.
timecodeoptSTRINGOptional burn-in timecode, for example 01:23:45:12, drawn in a dashed box in the top-right corner of the picture. Empty skips it.
font_pathoptSTRINGFont file for the subtitle and timecode. Empty falls back to DejaVu / Arial for a Latin line and to Noto CJK / YaHei / PingFang for a line that needs CJK glyphs.

Outputs (1)

NameTypeDescription
imageIMAGE—