mAI Frame Canvas Recut
The node that pads your video frames to a model-safe size — and remembers how to undo it
- frames
- recut_frames
- preview_first_frame
- extended_area_mask
- final_canvas_width
- final_canvas_height
- processing_canvas_width
- processing_canvas_height
- crop_x
- crop_y
- crop_width
- crop_height
Every serious video model has opinions about resolution, and most of them aren't nice. LTX-2.3 wants width and height divisible by 32 - off-grid values hard-fail instead of rounding. Others have a min-resolution window below which they smear and a max above which they OOM. So when you're outpainting a clip or feeding frames into a video model, your composition size is almost never the size the model accepts, and the usual "fix" is a pile of hand-wired padding and crop nodes.
mAI Frame Canvas Recut exists so you don't do that arithmetic. It takes an IMAGE batch, recuts it onto a canvas you define, re-pads that canvas to a model-safe processing size, and hands you the exact crop box to undo the padding afterward. The name's a little fancy, but the two-canvas design is genuinely the right way to think about this problem.
How it works: two canvases, not one
Feed it frames (a batch from Load Video or a frame sequence). Three sizes are in play:
- Your source frames get resized to
target_width×target_height. Note the README is explicit: there's no resize mode, it's always target-size logic, so keep the aspect ratio in mind or you'll get distortion. - The content canvas (
canvas_width×canvas_height) is where you actually want the video to live - your composition. - The processing canvas is what the model sees: content canvas plus
extra_padding_width/heightif asked, floored atmin_width/min_height, then rounded up to a multiple ofprocessing_multiple(default 32 - the LTX-2.3 number).max_width/max_heightact as a hard ceiling and can scale the whole composition down if your canvas exceeds them.
The frame gets positioned on the content canvas with anchor plus x_offset/y_offset, and everything not covered fills with your background_r/g/b (black by default). Fractional sizes round up so the node never undershoots the requested size - worth knowing, because your "720p" canvas can come out a bit larger.
The inputs that matter
You'll actually touch maybe five of these:
frames- your IMAGE batch. The only required connection.canvas_width/canvas_height- your composition size.processing_multiple- 32 for LTX-2.3; 1 effectively disables multiple alignment.min_width/min_height- the model's floor resolution.padding_strategy- where extra padding goes:centered,keep_anchor, or pinned to one corner. If you're outpainting one side only, this decides which edge your content sits on.
The rest (anchor, offsets, resize_algorithm, mask_expand/mask_feather) are fine to leave at defaults until you need them. mask_expand and mask_feather only affect the mask output, not the frames - a common first misread.
The outputs and the post-process loop
Beyond recut_frames (the batch on the processing canvas) and preview_first_frame (wire that straight into a Preview Image node), the star outputs are the metadata:
final_canvas_width/height- your exact requested size.processing_canvas_width/height- what the model actually got.crop_x/crop_y/crop_width/crop_height- the content box inside the processing canvas.
After generation, resize the model output to the processing size, crop with those values, then optionally resize to final_canvas_*. There's also extended_area_mask - white where the canvas is extended beyond the frame - which doubles as an outpainting mask if your model is mask-aware.
The frontend is the sleeper feature: the node draws a blue outline (content canvas) and white outline (frame) right on the node, and you can drag the image, drag handles to resize (Shift for free resize), and scroll to zoom - updating target_width/target_height live.
Install
No dependencies, no model downloads - it's pure PyTorch/PIL with no requirements.txt. Two ways:
- ComfyUI Manager: search "ComfyUI-mAI-FrameCanvas" and install, then restart.
- Manual:
cd ComfyUI/custom_nodes
git clone https://github.com/mAI-mathieu/ComfyUI-mAI-FrameCanvas
Restart ComfyUI and hard-refresh the browser (Ctrl+Shift+R) so the JS frontend loads.
Where people get burned
- Black bars you didn't ask for: default background is pure black, visible wherever your frame doesn't cover the canvas. Set
background_r/g/bbefore judging the output. - The min/max trap: if your
min_*andmax_*contradict each other (say, min 1024 over a max of 512), the node just scales your composition down again rather than erroring. Set them to the model's real window and letprocessing_multipledo the work. - Output node quirks: it's marked as an output node and hides its default image previews in favor of the custom canvas - if the interactive overlay isn't showing, it's almost always the stale-browser problem, not the node.
This is a young, low-traffic pack, so expect it to move. But the two-canvas plus crop-metadata pattern is solid, and once you've used it for one LTX or outpainting workflow, you'll keep reaching for it.
Inputs (22)
| Name | Type | Default | Description |
|---|---|---|---|
| frames | IMAGE | — | |
| canvas_width | INT | 12801–16384 | — |
| canvas_height | INT | 7201–16384 | — |
| processing_multiple | INT | 321–2048 | — |
| min_width | INT | 5121–16384 | — |
| min_height | INT | 5121–16384 | — |
| max_width | INT | 20481–16384 | — |
| max_height | INT | 20481–16384 | — |
| padding_strategy | COMBO | centered | 4 options: centered, keep_anchor, pad_right_bottom, pad_left_top |
| extra_padding_width | INT | 00–16384 | — |
| extra_padding_height | INT | 00–16384 | — |
| target_width | INT | 12801–16384 | — |
| target_height | INT | 7201–16384 | — |
| anchor | COMBO | top_left | 6 options: top_left, center, top_center, bottom_center, left_center, right_center |
| x_offset | INT | 0-16384–16384 | — |
| y_offset | INT | 0-16384–16384 | — |
| background_r | INT | 00–255 | — |
| background_g | INT | 00–255 | — |
| background_b | INT | 00–255 | — |
| resize_algorithm | COMBO | bicubic | 7 options: nearest, bilinear, bicubic, area, box, hamming, +1 |
| mask_expand | INT | 00–512 | — |
| mask_feather | INT | 00–512 | — |
Outputs (11)
| Name | Type | Description |
|---|---|---|
| recut_frames | IMAGE | — |
| preview_first_frame | IMAGE | — |
| extended_area_mask | MASK | — |
| final_canvas_width | INT | — |
| final_canvas_height | INT | — |
| processing_canvas_width | INT | — |
| processing_canvas_height | INT | — |
| crop_x | INT | — |
| crop_y | INT | — |
| crop_width | INT | — |
| crop_height | INT | — |