✂️ Magic Mask Edit 遮罩裁切、缩放与回贴
Crop to the mask, edit it big, paste it back — and nothing else moves
- image
- mask
- crop_info
- image
- mask
- crop_info
- mask_empty
If you've read anything about inpainting lately you've met the crop-and-stitch trick: cut the masked region out, let a model redraw just that patch at full resolution, paste it back. It became the 2026 default because the unmasked pixels never go through VAE encode/decode and come back bit-identical - a whole-frame edit model can't promise that.
MagicMaskEdit is that trick inside shigjfg's Magic Assistant pack - a Chinese-authored 12-in-1 utility suite. Same pattern as lquesada's Inpaint Crop and Stitch, different knobs.
One node, two jobs
Confusing on first open: you place two MagicMaskEdit nodes. Before your edit model, mode: crop. After it, mode: merge. Same class, two roles - these used to be two separate nodes, and both remain, deprecated, for old workflows.
In crop mode the node takes every pixel above mask_threshold, boxes it, adds padding pixels of context, shapes the box per crop_shape, then resizes it to fit inside target_width × target_height and rounds the canvas up to a multiple of size_multiple, filling the slack by replicating edge pixels. If your subject is jammed against the frame edge, the window slides inward instead of padding the source with black.
The clever part is what it saves. With the cropped image and mask, crop emits a crop_info blob carrying the original image tensor, the original soft mask, the crop box and the content box. So merge needs no original wired back in: one wire holds the geometry and the pixels. Merge resizes the edited patch to the crop box and composites with torch.lerp, weighted by that saved soft mask - everything else untouched. Note the deliberate asymmetry: mask_mode: binary hands the model a hard-edged, speck-preserving mask, while merge still blends with the soft original.
The settings that actually matter
Most of the nineteen inputs are situational. These are the ones you'll set:
padding(64) - context halo in original pixels. Too little and the model has no surroundings to blend into; too much defeats the point.resize_mode+target_width/target_height(1024×1024) - how big the patch gets. Intargetmode aspect is preserved, the canvas is the full target, and the slack is edge-padded.feather(16) - inward feathering per region, in original pixels; 0 gives a hard edge. Never bleeds outside the mask.input_layout(canvas) - the one that bites. Usecontentonly if the patch coming back has had its replicate padding stripped.empty_mask_mode(preserve) - no mask means keep the original, or edit the whole frame and restore the size.
Outputs are image, mask, crop_info and mask_empty. Crop's image and mask feed your edit model, its crop_info feeds merge, merge's image goes on to preview or save. mask_empty is the underrated one - gate the expensive branch on it.
The node face hides widgets that don't apply to the current mode; eight presets and the rest of the options live behind the ⚙ Settings & presets button.
Install
ComfyUI Manager → search Magic Assistant, or:
cd ComfyUI/custom_nodes
git clone https://github.com/shigjfg/ComfyUI-Magic-Assistant.git
cd ComfyUI-Magic-Assistant && pip install -r requirements.txt
The declared dependencies are just openai and aiohttp, and MagicMaskEdit needs no model files - the Klein and SDNQ loaders are the heavy ones. Keep ComfyUI on 0.29.0 or newer; the pack moved onto the new CoreModelPatcher APIs in v1.4.0. This node landed in v1.4.6; if it's missing, update the pack.
Where it breaks
Your edit came back identical. That's the mask-emptiness path: with empty_mask_mode: preserve, merge deliberately skips the paste when it found nothing above mask_threshold (0.001 by default - raise it and soft masks start failing the test). Check mask_empty, and read the status line the node prints on its face: crop box, output size, and whether it treated the mask as empty.
The paste is offset or zoomed. input_layout doesn't match reality: padding still in the image means canvas, padding gone means content.
Original image size differs from crop_info. You fed merge a different or resized original. Don't - crop already passed the original forward inside crop_info.
The edit model rejects the size. The 8-pixel canvas alignment suits SDXL and Flux; Qwen-Image-Edit-lineage models want multiples of 112, so set size_multiple to 112 and the target to 1008×1008. The canvas rounds up to a multiple of the alignment, so that lands cleanly.
Candidates won't merge. Merge takes an edited batch that matches the original, is a single image, or is an integer multiple of it - that's how you paste four variants of one inpaint in a pass, with batch_order choosing A B A B (repeat_batch) or A A B B (repeat_each).
No module named 'scipy'. The crop code imports scipy.ndimage for its feathering distance transform, and scipy isn't in the pack's requirements. It usually arrives with ComfyUI; lean installs don't. pip install scipy.
Inputs (21)
| Name | Type | Default | Description |
|---|---|---|---|
| mode | COMBO | crop | crop:接原图;merge:接编辑后的裁图和 crop_info。编辑模型前后各放一个本节点。 |
| image | IMAGE | crop 接原图;merge 接编辑结果。默认保留裁图完整画布,已去补边时在设置选 content。 | |
| resize_mode | COMBO | target | 4 options: target, longest_side, scale, none |
| target_width | INT | 10241–16384 | — |
| target_height | INT | 10241–16384 | — |
| padding | INT | 640–4096 | 原图像素的上下文留白;贴边时窗口向图内移动。 |
| mask_threshold | FLOAT | 0.0010–1 | — |
| empty_mask_mode | COMBO | preserve | 无遮罩或低于检测阈值时:preserve 保留原图;full_image 编辑整图,仍恢复原尺寸。 |
| upscale_method | COMBO | auto | auto:缩小用 area,放大用 bicubic,保留浮点精度。 |
| crop_shape | COMBO | target_ratio | 3 options: target_ratio, square, tight |
| scale_factor | FLOAT | 1.000.01–16 | — |
| scale_policy | COMBO | both | 3 options: both, upscale_only, downscale_only |
| size_multiple | INT | 81–256 | 补齐输出画布倍数,不拉伸图像;none 模式保持原尺寸。 |
| blend_mode | COMBO | mask | mask:只改遮罩;crop:替换整个裁切框。默认使用 crop_info 保存的原遮罩。 |
| feather | INT | 160–256 | 原图像素的向内羽化;小区域自适应保留自身最大强度,0 为硬边。遮罩外不变。 |
| blend_opacity | FLOAT | 1.000–1 | — |
| mask_mode | COMBO | binary | 供模型的遮罩:binary 二值且缩小保留细点;soft 保留软边。回贴仍使用源软遮罩。 |
| input_layout | COMBO | canvas | 编辑图与可选融合遮罩保留完整画布,或都已去掉裁切时的补边。 |
| batch_order | COMBO | repeat_batch | 多候选结果:repeat_batch 为 A B A B(ComfyUI批次重复);repeat_each 为 A A B B。 |
| maskopt | MASK | crop:原图坐标的源遮罩;merge:与编辑图布局相同的自定义融合遮罩,不接时使用保存的源软遮罩。 | |
| crop_infoopt | CROP_INFO | 回贴连接裁切实例的 crop_info,包含原图、源遮罩与坐标;裁切模式不使用此输入。 |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | crop:供编辑模型的裁图;merge:恢复原图尺寸后的结果。 |
| mask | MASK | crop:当前编辑画布中的模型遮罩;merge:原图坐标中的实际融合强度。 |
| crop_info | CROP_INFO | 裁切信息直接连回贴实例,不需要重复连原图。 |
| mask_empty | BOOLEAN | 裁切输入的遮罩是否全为空(按检测阈值);整图编辑模式即使为 True 仍会编辑。 |