diff --git a/README.md b/README.md index b00d722..cfb5703 100644 --- a/README.md +++ b/README.md @@ -3,142 +3,201 @@ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![ComfyUI](https://img.shields.io/badge/ComfyUI-Custom%20Node-blue.svg)](https://github.com/comfyanonymous/ComfyUI) -**增强版遮罩编辑器**:集成 Photopea 图像编辑 + 可拖动选区调整 + 多语言支持 +A ComfyUI custom node for inpainting workflows with integrated Photopea editing and adjustable region selection. + +[中文文档](README_CN.md) --- -## 📚 文档索引 +## Key Features -| 文档 | 说明 | 目标读者 | -|------|------|---------| -| [`docs/QUICKSTART.md`](docs/QUICKSTART.md) | ⚡ 5 分钟快速开始 | 新接手开发的工程师 | -| [`docs/HANDOFF.md`](docs/HANDOFF.md) | 📋 完整交接文档 | 开发团队 | -| [`docs/implementation-plan.md`](docs/implementation-plan.md) | 💻 详细实现方案 | 后端/前端开发 | -| [`docs/technical-validation.md`](docs/technical-validation.md) | 🧪 技术验证清单 | 测试工程师 | -| [`DEVLOG.md`](DEVLOG.md) | 📔 开发日志 | 了解历史问题 | +### 1. Adjustable Reference Region + +ComfyUI's native inpainting nodes expand the reference region uniformly from the mask boundary. This fixed pattern has limitations: + +- **Edge Area Issues**: When the reference region extends beyond image boundaries, invalid areas outside the image may cause suboptimal generation results +- **Fixed Expansion Direction**: The expansion direction is fixed to the normal of the mask boundary, unable to flexibly adjust based on image content + +**Our Solution**: Manually drag and resize the reference region position and dimensions, allowing the model to reference the correct image context. + +### 2. Integrated Photopea Image Editing + +ComfyUI does not have built-in image editing capabilities. Modifying source images typically requires external tools. + +**Our Solution**: Integrated Photopea online image editor, supporting professional editing operations such as liquefy, clone stamp, healing, and color adjustments directly in the browser. Edit results can be saved directly back to the node. + +### 3. Professional Mask Editing with Feathering Control + +ComfyUI's built-in mask editor is suitable for quick operations, but has limited functionality for drawing complex masks and precise feathering effects. Feathering is usually generated algorithmically. + +**Our Solution**: +- Photopea dual-layer mask editing mode +- Manual drawing of masks with arbitrary shapes and feathering degrees +- User-controlled feathering effects, not algorithm-estimated --- -## 🎯 功能特性 +## Features -- 🎨 **Photopea 集成** - 完整的 Photoshop 级编辑功能(液化、仿制图章等) -- 🎭 **蒙版编辑** - 双图层模式编辑蒙版,支持羽化效果 -- 📐 **可拖动选区** - 手动调整参考区域位置和大小 -- 🔄 **自动蒙版检测** - 从 Alpha 通道提取,无蒙版时友好报错 -- 🌐 **多语言支持** - 中英文界面,自动跟随 ComfyUI 设置 +- **Reference Region Adjustment** - Drag position, resize, constraint validation +- **Photopea Image Editing** - Liquefy, clone stamp, healing, filters, etc. +- **Photopea Mask Editing** - Dual-layer mode with precise feathering control +- **Auto Mask Detection** - Extract mask from PNG alpha channel automatically +- **Multi-language Support** - Chinese and English UI, auto-adapts to ComfyUI language settings +- **Quick Paste** - Support Ctrl+V to paste images directly --- -## 📦 安装 +## Installation -### 方法 1:ComfyUI Manager(推荐) +### Method 1: ComfyUI Manager (Recommended) -在 ComfyUI Manager 中搜索 "Inpaint Region Editor"。 +Search for "Inpaint Region Editor" in ComfyUI Manager. -### 方法 2:手动安装 +### Method 2: Manual Installation ```bash cd ComfyUI/custom_nodes -git clone https://github.com/YOUR_USERNAME/ComfyUI-InpaintRegionEditor.git +git clone https://github.com/abc-lee/ComfyUI-InpaintRegionEditor.git ``` -重启 ComfyUI。 +Restart ComfyUI. --- -## 🚀 使用方法 +## Usage -1. 添加 **Inpaint Region Editor** 节点 -2. 上传图像(需要带 Alpha 通道的 PNG) -3. 右键点击节点选择操作: - - **编辑图像(Photopea)** - 编辑图像本身 - - **编辑蒙版(Photopea)** - 双图层蒙版编辑,支持羽化 - - **Open in MaskEditor** - 使用 ComfyUI 自带蒙版编辑器 -4. 调整扩散像素数或拖动选区框 -5. 执行工作流 +### Node Interface + +![Node Interface](images/node-overview.png) + +The node displays the image preview area, orange reference region box (with size annotation), and parameter controls. + +### Context Menu + +![Context Menu](images/context-menu.png) + +| Option | Description | +|--------|-------------| +| Edit Image (Photopea) | Edit the image in Photopea | +| Edit Mask (Photopea) | Dual-layer mask editing mode | + +### Basic Workflow + +1. Add the **Inpaint Region Editor** node to your workflow +2. Upload a PNG image with alpha channel (transparent areas = mask) +3. The node automatically extracts the mask and calculates the initial reference region +4. Edit image or mask as needed (context menu) +5. Drag the reference region to the desired position +6. Connect outputs to downstream nodes + +### Mask Effect + +![Mask Example](images/mask-example.png) + +The black area in the image represents the mask, indicating the region to be repainted by the model. + +### Reference Region Adjustment + +- **Move Position**: Drag inside the reference region +- **Resize**: Drag the edges or corners +- **Constraint Rules**: Reference region always contains the mask and stays within image boundaries --- -## 📤 节点输出 +## Node Parameters -| 输出 | 类型 | 说明 | -|------|------|------| -| `image` | IMAGE | 编辑后的图像 | -| `mask` | MASK | 局部重绘蒙版 | -| `region_top` | INT | 选区顶部坐标 | -| `region_left` | INT | 选区左侧坐标 | -| `region_width` | INT | 选区宽度 | -| `region_height` | INT | 选区高度 | +### Inputs + +| Parameter | Type | Description | +|-----------|------|-------------| +| `image` | IMAGE | Input image (supports upload, paste) | +| `padding` | INT | Reference region expansion pixels (default: 64, range: 0-512) | + +### Outputs + +| Output | Type | Description | +|--------|------|-------------| +| `image` | IMAGE | RGB image (without alpha) | +| `mask` | MASK | Mask extracted from alpha channel | +| `region_top` | INT | Reference region top Y coordinate | +| `region_left` | INT | Reference region left X coordinate | +| `region_width` | INT | Reference region width | +| `region_height` | INT | Reference region height | --- -## 📘 核心概念 +## Concepts -| 概念 | 目的 | 说明 | -|------|------|------| -| **遮罩 (Mask)** | 定义重绘区域 | AI 在这个区域内生成新内容 | -| **选区 (Region)** | 定义参考区域 | AI 参考这个区域内的原图内容 | +| Concept | Definition | Purpose | +|---------|------------|---------| +| **Mask** | Specifies the area to repaint | The model generates new content within this region | +| **Reference Region** | The image area the model references | The model uses original pixels in this region for content generation | -**约束**:选区必须 >= 遮罩 +**Constraint**: The reference region must fully contain the mask. + +**Calculation**: Reference region boundary = Mask bounding box + padding (expanded in all directions) --- -## ✅ 已完成功能 +## Notes -- [x] 基础节点逻辑(`nodes.py`) -- [x] Photopea iframe 集成 -- [x] 右键菜单打开 Photopea(编辑图像/编辑蒙版) -- [x] 图像预览(自己渲染,不依赖 ComfyUI) -- [x] 选区框绘制(橙色)+ 遮罩区域显示 -- [x] Alpha 通道自动检测蒙版 -- [x] 选区框拖动和调整大小 -- [x] 选区约束(必须框住蒙版) -- [x] Ctrl+V 粘贴图片 -- [x] MaskEditor 集成 -- [x] 多语言支持(中英文) -- [x] 羽化效果支持 +1. **Image Format**: PNG images with alpha channel are required. If the image has no alpha channel, the node will prompt to create a mask. + +2. **Network Dependency**: Photopea loads from CDN, approximately 10MB on first load, then uses browser cache. + +3. **Image Size**: Images larger than 2048×2048 are not recommended, as they may cause Photopea performance issues. + +4. **Reference Region Constraints**: + - Reference region always contains the mask area + - Reference region never exceeds image boundaries + - Reference region is automatically recalculated when mask changes + +5. **Feathering Control**: + - Use semi-transparent brush in Photopea to draw gray areas for feathering + - Alpha values 1-254 produce gradual transparency transitions --- -## 🔧 技术细节 +## Example Workflow -- 使用 Photopea [postMessage API](https://www.photopea.com/api/) -- 所有消息 origin 都经过验证(只接受 `https://www.photopea.com`) -- 图像处理在浏览器本地完成 +This node includes an example workflow file `workflow.json` demonstrating an efficient inpainting process: + +![Workflow](images/workflow.png) + +### Workflow Principle + +1. **Region Cropping** - Crop the reference region from the original image based on `region_*` coordinates +2. **Upscaling** - Scale the cropped region to the model's optimal working size (e.g., 1024×1024) +3. **High-Resolution Inpainting** - Sample at the upscaled size to ensure fine detail generation +4. **Downscaling** - Scale back to original size after inpainting +5. **Compositing** - Precisely composite the inpainted result back to the corresponding position in the original image + +### Advantages + +- **Finer Details** - Inpainting is performed at high resolution, avoiding detail loss from small-size sampling +- **Smoother Edges** - Upscale before sampling, downscale after, resulting in smoother edge transitions +- **Any Size Compatible** - High-quality generation results regardless of how small the inpainting region is in the original image + +### Usage + +Drag `workflow.json` into ComfyUI to load the complete workflow. --- -## ⚡ 限制 - -- 需要网络连接(Photopea 从 CDN 加载) -- 首次加载约 10MB,之后缓存 -- Photopea 无法通过脚本直接访问图层蒙版(官方 API 限制) - ---- - -## 🙏 致谢 +## Credits - [Photopea](https://www.photopea.com/) by Ivan Kutskir - [ComfyUI](https://github.com/comfyanonymous/ComfyUI) -- [ComfyUI-Impact-Pack](https://github.com/ltdrdata/ComfyUI-Impact-Pack) - 选区框实现参考 +- [ComfyUI-Impact-Pack](https://github.com/ltdrdata/ComfyUI-Impact-Pack) --- -## 📄 许可证 +## License -MIT License - 详见 [LICENSE](LICENSE) 文件。 +MIT License - See [LICENSE](LICENSE) file. -### Photopea 使用条款 -- API 完全免费,可用于任何目的(包括商业用途) -- 你的作品完全归你所有 -- 无需标注使用了 Photopea(但建议标注) - ---- - -## 📝 更新日志 - -详见 [CHANGELOG.md](CHANGELOG.md)。 - ---- - -*最后更新:2026-03-03* +### Photopea Terms of Use +- API is completely free for commercial use +- User retains full copyright of their work +- No attribution required diff --git a/README_CN.md b/README_CN.md new file mode 100644 index 0000000..a772939 --- /dev/null +++ b/README_CN.md @@ -0,0 +1,201 @@ +# ComfyUI Inpaint Region Editor + +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) +[![ComfyUI](https://img.shields.io/badge/ComfyUI-Custom%20Node-blue.svg)](https://github.com/comfyanonymous/ComfyUI) + +一个用于局部重绘(Inpaint)工作流的 ComfyUI 自定义节点,集成 Photopea 图像编辑与可调整参考区功能。 + +--- + +## 核心优势 + +### 1. 可调整参考区方向与位置 + +ComfyUI 原生的局部重绘节点,参考区只能以蒙版边界为中心向外均匀扩散。这种固定模式存在以下局限: + +- **边缘区域问题**:当参考区延伸至图像边界时,边界外的无效区域可能导致模型产生不理想的生成结果 +- **参考方向单一**:扩散方向固定为蒙版边界的法向,无法根据图像内容灵活调整 + +**本节点解决方案**:支持手动拖动和调整参考区的位置与尺寸,使模型能够参考正确的图像上下文。 + +### 2. 集成 Photopea 图像编辑 + +ComfyUI 本身不具备图像编辑功能,修改源图像通常需要外部工具。 + +**本节点解决方案**:集成 Photopea 在线图像编辑器,支持在浏览器内完成液化、仿制图章、修补、色彩调整等专业编辑操作,编辑结果可直接保存回节点。 + +### 3. 专业级蒙版编辑与羽化控制 + +ComfyUI 内置的蒙版编辑器适用于快速操作,但在绘制复杂蒙版和精细羽化效果时功能有限,羽化效果通常依赖算法自动生成。 + +**本节点解决方案**: +- 提供 Photopea 双图层蒙版编辑模式 +- 支持手动绘制任意形状和羽化程度的蒙版 +- 羽化效果由用户精确控制,而非算法估算 + +--- + +## 功能特性 + +- **参考区调整** - 拖动位置、调整尺寸、约束验证 +- **Photopea 图像编辑** - 液化、仿制图章、修补、滤镜等 +- **Photopea 蒙版编辑** - 双图层模式,支持精确羽化控制 +- **自动蒙版检测** - 从 PNG Alpha 通道自动提取蒙版 +- **多语言支持** - 中英文界面,自动适配 ComfyUI 语言设置 +- **快捷粘贴** - 支持 Ctrl+V 直接粘贴图像 + +--- + +## 安装 + +### 方法 1:ComfyUI Manager(推荐) + +在 ComfyUI Manager 中搜索 "Inpaint Region Editor"。 + +### 方法 2:手动安装 + +```bash +cd ComfyUI/custom_nodes +git clone https://github.com/YOUR_USERNAME/ComfyUI-InpaintRegionEditor.git +``` + +重启 ComfyUI。 + +--- + +## 使用方法 + +### 节点界面 + +![节点界面](images/node-overview.png) + +节点显示图像预览区域、橙色参考区框(标注尺寸)、参数控件。 + +### 右键菜单 + +![右键菜单](images/context-menu.png) + +| 选项 | 说明 | +|------|------| +| 编辑图像(Photopea) | 在 Photopea 中编辑图像 | +| 编辑蒙版(Photopea) | 双图层蒙版编辑模式 | + +### 基本流程 + +1. 添加 **Inpaint Region Editor** 节点至工作流 +2. 上传带 Alpha 通道的 PNG 图像(透明区域即为蒙版) +3. 节点自动提取蒙版并计算初始参考区 +4. 根据需要编辑图像或蒙版(右键菜单) +5. 拖动参考区到合适位置 +6. 连接输出至下游节点 + +### 蒙版效果 + +![蒙版示例](images/mask-example.png) + +图像中的黑色区域为蒙版,指示模型需要重绘的区域。 + +### 参考区调整 + +- **移动位置**:拖动参考区内部 +- **调整尺寸**:拖动边缘或角落 +- **约束规则**:参考区始终包含蒙版,不超出图像边界 + +--- + +## 节点参数 + +### 输入 + +| 参数 | 类型 | 说明 | +|------|------|------| +| `image` | IMAGE | 输入图像(支持上传、粘贴) | +| `padding` | INT | 参考区扩散像素数(默认 64,范围 0-512) | + +### 输出 + +| 输出 | 类型 | 说明 | +|------|------|------| +| `image` | IMAGE | RGB 图像(不含 Alpha) | +| `mask` | MASK | 蒙版(从 Alpha 通道提取) | +| `region_top` | INT | 参考区顶部 Y 坐标 | +| `region_left` | INT | 参考区左侧 X 坐标 | +| `region_width` | INT | 参考区宽度 | +| `region_height` | INT | 参考区高度 | + +--- + +## 概念说明 + +| 概念 | 定义 | 作用 | +|------|------|------| +| **蒙版 (Mask)** | 指定需要重绘的区域 | 模型在该区域内生成新内容 | +| **参考区 (Region)** | 模型参考的图像区域 | 模型根据该区域内的原始像素进行内容生成 | + +**约束关系**:参考区必须完全包含蒙版。 + +**计算方式**:参考区边界 = 蒙版边界框 + padding(向四周扩展) + +--- + +## 注意事项 + +1. **图像格式要求**:需上传带 Alpha 通道的 PNG 图像。若图像无 Alpha 通道,节点将提示创建蒙版。 + +2. **网络依赖**:Photopea 从 CDN 加载,首次加载约 10MB,后续使用浏览器缓存。 + +3. **图像尺寸**:建议图像尺寸不超过 2048×2048,过大图像可能导致 Photopea 性能下降。 + +4. **参考区约束**: + - 参考区始终包含蒙版区域 + - 参考区不会超出图像边界 + - 蒙版变化时参考区自动重新计算 + +5. **羽化控制**: + - 在 Photopea 中使用半透明画笔绘制灰色区域实现羽化 + - Alpha 值 1-254 产生渐进透明过渡效果 + +--- + +## 示例工作流 + +本节点附带示例工作流文件 `workflow.json`,演示一套高效的局部重绘流程: + +![工作流截图](images/workflow.png) + +### 工作流原理 + +1. **区域裁剪** - 根据 `region_*` 坐标从原图中裁剪出参考区域 +2. **放大处理** - 将裁剪区域放大至模型最佳工作尺寸(如 1024×1024) +3. **高分辨率重绘** - 在放大后的尺寸上进行采样,确保生成细节清晰 +4. **缩小还原** - 重绘完成后缩小回原始尺寸 +5. **合成回原图** - 将重绘结果精确合成回原图对应位置 + +### 优势 + +- **细节更清晰** - 重绘在高分辨率下进行,避免小尺寸采样导致的细节丢失 +- **边缘更自然** - 放大后采样,缩小后合成,边缘过渡更平滑 +- **适配任意尺寸** - 无论原图中重绘区域多小,都能获得高质量的生成效果 + +### 使用方法 + +将 `workflow.json` 拖入 ComfyUI 即可加载完整工作流。 + +--- + +## 致谢 + +- [Photopea](https://www.photopea.com/) by Ivan Kutskir +- [ComfyUI](https://github.com/comfyanonymous/ComfyUI) +- [ComfyUI-Impact-Pack](https://github.com/ltdrdata/ComfyUI-Impact-Pack) + +--- + +## 许可证 + +MIT License - 详见 [LICENSE](LICENSE) 文件。 + +### Photopea 使用条款 +- API 完全免费,支持商业用途 +- 用户作品版权归用户所有 +- 无强制署名要求 diff --git a/images/context-menu.png b/images/context-menu.png new file mode 100644 index 0000000..4ce4adc Binary files /dev/null and b/images/context-menu.png differ diff --git a/images/mask-example.png b/images/mask-example.png new file mode 100644 index 0000000..e300160 Binary files /dev/null and b/images/mask-example.png differ diff --git a/images/node-detail.png b/images/node-detail.png new file mode 100644 index 0000000..8dfb8df Binary files /dev/null and b/images/node-detail.png differ diff --git a/images/node-overview.png b/images/node-overview.png new file mode 100644 index 0000000..5c8d15d Binary files /dev/null and b/images/node-overview.png differ diff --git a/images/workflow.png b/images/workflow.png new file mode 100644 index 0000000..f64964a Binary files /dev/null and b/images/workflow.png differ diff --git a/web/extension.js b/web/extension.js index 2d9f33e..2e421ff 100644 --- a/web/extension.js +++ b/web/extension.js @@ -1267,33 +1267,15 @@ app.registerExtension({ if (hasPp) return; const node = this; const imgW = node.widgets?.find(w => w.name === "image"); - options.push(null); - options.push({ - content: t('menu.editImage'), - callback: function() { imgW?.value ? showPhotopeaModal(node, imgW.value) : alert(t('menu.selectImageFirst')); } - }); - options.push({ - content: t('menu.editMask'), - callback: function() { imgW?.value ? showPhotopeaMaskModal(node, imgW.value) : alert(t('menu.selectImageFirst')); } - }); - // Open in MaskEditor - 使用正确的命令调用 - options.push({ - content: t('menu.openMaskEditor'), - callback: function() { - if (!imgW?.value) { alert(t('menu.selectImageFirst')); return; } - const data = nodeImageData.get(node.id); - if (!data?.imageUrl) { alert(t('menu.imageNotLoaded')); return; } - - // 创建带有正确 URL 的图像对象供 MaskEditor 使用 - const maskEditorImg = new Image(); - maskEditorImg.src = data.imageUrl; - node.imgs = [maskEditorImg]; - - // 选中节点并执行命令 - app.canvas.selectNode(node); - app.extensionManager.command.execute("Comfy.MaskEditor.OpenMaskEditor"); - } - }); + options.push(null); + options.push({ + content: t('menu.editImage'), + callback: function() { imgW?.value ? showPhotopeaModal(node, imgW.value) : alert(t('menu.selectImageFirst')); } + }); + options.push({ + content: t('menu.editMask'), + callback: function() { imgW?.value ? showPhotopeaMaskModal(node, imgW.value) : alert(t('menu.selectImageFirst')); } + }); }; // 自己绘制图像和选区框 diff --git a/web/locales/en/main.json b/web/locales/en/main.json index a5eabf2..a91598a 100644 --- a/web/locales/en/main.json +++ b/web/locales/en/main.json @@ -2,9 +2,7 @@ "menu": { "editImage": "Edit Image (Photopea)", "editMask": "Edit Mask (Photopea)", - "openMaskEditor": "Open in MaskEditor", - "selectImageFirst": "Please select an image first", - "imageNotLoaded": "Image not loaded yet" + "selectImageFirst": "Please select an image first" }, "photopea": { "editHint": "Click Save after editing", diff --git a/web/locales/zh/main.json b/web/locales/zh/main.json index 8f44c4b..0ef7e59 100644 --- a/web/locales/zh/main.json +++ b/web/locales/zh/main.json @@ -2,9 +2,7 @@ "menu": { "editImage": "编辑图像(Photopea)", "editMask": "编辑蒙版(Photopea)", - "openMaskEditor": "Open in MaskEditor", - "selectImageFirst": "请先选择图像", - "imageNotLoaded": "图像尚未加载完成" + "selectImageFirst": "请先选择图像" }, "photopea": { "editHint": "编辑后点击保存", diff --git a/workflow.json b/workflow.json new file mode 100644 index 0000000..1de073a --- /dev/null +++ b/workflow.json @@ -0,0 +1 @@ +{"id":"b0cd2e5d-48c7-4c75-897d-0224921c6709","revision":0,"last_node_id":64,"last_link_id":461,"nodes":[{"id":18,"type":"PrimitiveInt","pos":[89.8182478493147,364.83923439420977],"size":[270,82],"flags":{},"order":0,"mode":0,"inputs":[{"localized_name":"value","name":"value","type":"INT","widget":{"name":"value"},"link":null}],"outputs":[{"localized_name":"INT","name":"INT","type":"INT","links":[23,24]}],"properties":{"Node name for S&R":"PrimitiveInt"},"widgets_values":[1024,"fixed"],"color":"#232","bgcolor":"#353"},{"id":16,"type":"MaskToImage","pos":[381.574217119286,198.37138707777433],"size":[193.2779296875,26],"flags":{"collapsed":true},"order":9,"mode":0,"inputs":[{"localized_name":"mask","name":"mask","type":"MASK","link":21}],"outputs":[{"localized_name":"IMAGE","name":"IMAGE","type":"IMAGE","links":[22]}],"properties":{"Node name for S&R":"MaskToImage"},"widgets_values":[]},{"id":17,"type":"ImageScaleToMaxDimension","pos":[555.7533257488516,169.51378030801953],"size":[270,82],"flags":{},"order":12,"mode":0,"inputs":[{"localized_name":"image","name":"image","type":"IMAGE","link":22},{"localized_name":"upscale_method","name":"upscale_method","type":"COMBO","widget":{"name":"upscale_method"},"link":null},{"localized_name":"largest_size","name":"largest_size","type":"INT","widget":{"name":"largest_size"},"link":23}],"outputs":[{"localized_name":"IMAGE","name":"IMAGE","type":"IMAGE","links":[25]}],"properties":{"Node name for S&R":"ImageScaleToMaxDimension"},"widgets_values":["lanczos",512]},{"id":15,"type":"ImageScaleToMaxDimension","pos":[555.5943306702312,5.11286901365998],"size":[270,82],"flags":{},"order":8,"mode":0,"inputs":[{"localized_name":"image","name":"image","type":"IMAGE","link":20},{"localized_name":"upscale_method","name":"upscale_method","type":"COMBO","widget":{"name":"upscale_method"},"link":null},{"localized_name":"largest_size","name":"largest_size","type":"INT","widget":{"name":"largest_size"},"link":24}],"outputs":[{"localized_name":"IMAGE","name":"IMAGE","type":"IMAGE","links":[26]}],"properties":{"Node name for S&R":"ImageScaleToMaxDimension"},"widgets_values":["lanczos",512]},{"id":20,"type":"VAEEncode","pos":[876.2375577816651,4.685189185143852],"size":[140,46],"flags":{},"order":11,"mode":0,"inputs":[{"localized_name":"pixels","name":"pixels","type":"IMAGE","link":26},{"localized_name":"vae","name":"vae","type":"VAE","link":40}],"outputs":[{"localized_name":"LATENT","name":"LATENT","type":"LATENT","links":[28]}],"properties":{"Node name for S&R":"VAEEncode"},"widgets_values":[]},{"id":27,"type":"CLIPTextEncode","pos":[77.36281037229134,528.4507520561906],"size":[400,200],"flags":{},"order":4,"mode":0,"inputs":[{"localized_name":"clip","name":"clip","type":"CLIP","link":38},{"localized_name":"text","name":"text","type":"STRING","widget":{"name":"text"},"link":null}],"outputs":[{"localized_name":"CONDITIONING","name":"CONDITIONING","type":"CONDITIONING","links":[33]}],"properties":{"Node name for S&R":"CLIPTextEncode"},"widgets_values":[""],"color":"#232","bgcolor":"#353"},{"id":28,"type":"CLIPTextEncode","pos":[504.32168365329335,527.054043888534],"size":[400,200],"flags":{},"order":5,"mode":0,"inputs":[{"localized_name":"clip","name":"clip","type":"CLIP","link":39},{"localized_name":"text","name":"text","type":"STRING","widget":{"name":"text"},"link":null}],"outputs":[{"localized_name":"CONDITIONING","name":"CONDITIONING","type":"CONDITIONING","links":[34]}],"properties":{"Node name for S&R":"CLIPTextEncode"},"widgets_values":[""],"color":"#232","bgcolor":"#353"},{"id":22,"type":"SetLatentNoiseMask","pos":[1059.2909767244785,3.6270769369195044],"size":[188.1373046875,46],"flags":{},"order":16,"mode":0,"inputs":[{"localized_name":"samples","name":"samples","type":"LATENT","link":28},{"localized_name":"mask","name":"mask","type":"MASK","link":29}],"outputs":[{"localized_name":"LATENT","name":"LATENT","type":"LATENT","links":[35]}],"properties":{"Node name for S&R":"SetLatentNoiseMask"},"widgets_values":[]},{"id":23,"type":"CheckpointLoaderSimple","pos":[493.200923924455,358.09468009207217],"size":[273.4576171875,98],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"ckpt_name","name":"ckpt_name","type":"COMBO","widget":{"name":"ckpt_name"},"link":null}],"outputs":[{"localized_name":"MODEL","name":"MODEL","type":"MODEL","links":[31]},{"localized_name":"CLIP","name":"CLIP","type":"CLIP","links":[38,39]},{"localized_name":"VAE","name":"VAE","type":"VAE","links":[37,40]}],"properties":{"Node name for S&R":"CheckpointLoaderSimple"},"widgets_values":["juggernautXL_ragnarokBy.safetensors"],"color":"#232","bgcolor":"#353"},{"id":29,"type":"VAEDecode","pos":[1265.1467146165203,310.57485902431654],"size":[140,46],"flags":{},"order":19,"mode":0,"inputs":[{"localized_name":"samples","name":"samples","type":"LATENT","link":36},{"localized_name":"vae","name":"vae","type":"VAE","link":37}],"outputs":[{"localized_name":"IMAGE","name":"IMAGE","type":"IMAGE","links":[41]}],"properties":{"Node name for S&R":"VAEDecode"},"widgets_values":[]},{"id":12,"type":"CropMask","pos":[88.40112471356343,169.89894588597946],"size":[270,130],"flags":{},"order":7,"mode":0,"inputs":[{"localized_name":"mask","name":"mask","type":"MASK","link":449},{"localized_name":"x","name":"x","type":"INT","widget":{"name":"x"},"link":454},{"localized_name":"y","name":"y","type":"INT","widget":{"name":"y"},"link":451},{"localized_name":"width","name":"width","type":"INT","widget":{"name":"width"},"link":457},{"localized_name":"height","name":"height","type":"INT","widget":{"name":"height"},"link":460}],"outputs":[{"localized_name":"MASK","name":"MASK","type":"MASK","links":[21,45]}],"properties":{"Node name for S&R":"CropMask"},"widgets_values":[0,0,512,512]},{"id":9,"type":"ImageCrop","pos":[86.55967262116872,-8.815858713708549],"size":[270,130],"flags":{"collapsed":false},"order":6,"mode":0,"inputs":[{"localized_name":"image","name":"image","type":"IMAGE","link":447},{"localized_name":"width","name":"width","type":"INT","widget":{"name":"width"},"link":456},{"localized_name":"height","name":"height","type":"INT","widget":{"name":"height"},"link":459},{"localized_name":"x","name":"x","type":"INT","widget":{"name":"x"},"link":453},{"localized_name":"y","name":"y","type":"INT","widget":{"name":"y"},"link":450}],"outputs":[{"localized_name":"IMAGE","name":"IMAGE","type":"IMAGE","links":[20,46]}],"properties":{"Node name for S&R":"ImageCrop"},"widgets_values":[512,512,0,0]},{"id":34,"type":"MaskToImage","pos":[956.967176190708,589.8322370885039],"size":[193.2779296875,26],"flags":{},"order":13,"mode":0,"inputs":[{"localized_name":"mask","name":"mask","type":"MASK","link":47}],"outputs":[{"localized_name":"IMAGE","name":"IMAGE","type":"IMAGE","links":[48]}],"properties":{"Node name for S&R":"MaskToImage"},"widgets_values":[]},{"id":36,"type":"ImageCompositeMasked","pos":[1250.31436820752,610.1287538498983],"size":[270,146],"flags":{},"order":21,"mode":0,"inputs":[{"localized_name":"destination","name":"destination","type":"IMAGE","link":448},{"localized_name":"source","name":"source","type":"IMAGE","link":52},{"localized_name":"mask","name":"mask","shape":7,"type":"MASK","link":51},{"localized_name":"x","name":"x","type":"INT","widget":{"name":"x"},"link":455},{"localized_name":"y","name":"y","type":"INT","widget":{"name":"y"},"link":452},{"localized_name":"resize_source","name":"resize_source","type":"BOOLEAN","widget":{"name":"resize_source"},"link":null}],"outputs":[{"localized_name":"IMAGE","name":"IMAGE","type":"IMAGE","links":[56]}],"properties":{"Node name for S&R":"ImageCompositeMasked"},"widgets_values":[0,0,false]},{"id":35,"type":"PreviewImage","pos":[-631.8941757429558,561.369017611269],"size":[318.08029137615574,246],"flags":{},"order":17,"mode":0,"inputs":[{"localized_name":"images","name":"images","type":"IMAGE","link":49}],"outputs":[],"properties":{"Node name for S&R":"PreviewImage"},"widgets_values":[]},{"id":37,"type":"PreviewImage","pos":[-669.5822101842551,849.1659299260318],"size":[652.1263281405786,386.8162766444982],"flags":{},"order":22,"mode":0,"inputs":[{"localized_name":"images","name":"images","type":"IMAGE","link":56}],"outputs":[],"properties":{"Node name for S&R":"PreviewImage"},"widgets_values":[]},{"id":19,"type":"ImageToMask","pos":[851.026266157924,115.36164648041154],"size":[270,58],"flags":{"collapsed":true},"order":14,"mode":0,"inputs":[{"localized_name":"image","name":"image","type":"IMAGE","link":25},{"localized_name":"channel","name":"channel","type":"COMBO","widget":{"name":"channel"},"link":null}],"outputs":[{"localized_name":"MASK","name":"MASK","type":"MASK","links":[29]}],"properties":{"Node name for S&R":"ImageToMask"},"widgets_values":["red"]},{"id":25,"type":"DifferentialDiffusion","pos":[883.6443435192343,178.21559789393527],"size":[286.6919921875,58],"flags":{},"order":3,"mode":0,"inputs":[{"localized_name":"model","name":"model","type":"MODEL","link":31},{"localized_name":"strength","name":"strength","shape":7,"type":"FLOAT","widget":{"name":"strength"},"link":null}],"outputs":[{"localized_name":"MODEL","name":"MODEL","type":"MODEL","links":[32]}],"properties":{"Node name for S&R":"DifferentialDiffusion"},"widgets_values":[1]},{"id":32,"type":"ImpactGaussianBlurMask","pos":[824.2799002633745,371.5436802798233],"size":[270,82],"flags":{},"order":10,"mode":0,"inputs":[{"localized_name":"mask","name":"mask","type":"MASK","link":45},{"localized_name":"kernel_size","name":"kernel_size","type":"INT","widget":{"name":"kernel_size"},"link":null},{"localized_name":"sigma","name":"sigma","type":"FLOAT","widget":{"name":"sigma"},"link":null}],"outputs":[{"localized_name":"MASK","name":"MASK","type":"MASK","links":[47,51]}],"properties":{"Node name for S&R":"ImpactGaussianBlurMask"},"widgets_values":[5,10],"color":"#232","bgcolor":"#353"},{"id":33,"type":"ImageBlend","pos":[-251.39701128148374,594.6995534303362],"size":[270,102],"flags":{},"order":15,"mode":0,"inputs":[{"localized_name":"image1","name":"image1","type":"IMAGE","link":46},{"localized_name":"image2","name":"image2","type":"IMAGE","link":48},{"localized_name":"blend_factor","name":"blend_factor","type":"FLOAT","widget":{"name":"blend_factor"},"link":null},{"localized_name":"blend_mode","name":"blend_mode","type":"COMBO","widget":{"name":"blend_mode"},"link":null}],"outputs":[{"localized_name":"IMAGE","name":"IMAGE","type":"IMAGE","links":[49]}],"properties":{"Node name for S&R":"ImageBlend"},"widgets_values":[0.5,"overlay"]},{"id":26,"type":"KSampler","pos":[1258.0785247983822,7.013036131237428],"size":[270,262],"flags":{},"order":18,"mode":0,"inputs":[{"localized_name":"model","name":"model","type":"MODEL","link":32},{"localized_name":"positive","name":"positive","type":"CONDITIONING","link":33},{"localized_name":"negative","name":"negative","type":"CONDITIONING","link":34},{"localized_name":"latent_image","name":"latent_image","type":"LATENT","link":35},{"localized_name":"seed","name":"seed","type":"INT","widget":{"name":"seed"},"link":null},{"localized_name":"steps","name":"steps","type":"INT","widget":{"name":"steps"},"link":null},{"localized_name":"cfg","name":"cfg","type":"FLOAT","widget":{"name":"cfg"},"link":null},{"localized_name":"sampler_name","name":"sampler_name","type":"COMBO","widget":{"name":"sampler_name"},"link":null},{"localized_name":"scheduler","name":"scheduler","type":"COMBO","widget":{"name":"scheduler"},"link":null},{"localized_name":"denoise","name":"denoise","type":"FLOAT","widget":{"name":"denoise"},"link":null}],"outputs":[{"localized_name":"LATENT","name":"LATENT","type":"LATENT","links":[36]}],"properties":{"Node name for S&R":"KSampler"},"widgets_values":[512767367336106,"randomize",35,5,"dpmpp_2m_sde_gpu","karras",0.45]},{"id":64,"type":"InpaintRegionEditor","pos":[-678.4760098323817,-21.356073747018826],"size":[574.7151652436447,536.647482237351],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"image","name":"image","type":"COMBO","widget":{"name":"image"},"link":null},{"localized_name":"padding","name":"padding","type":"INT","widget":{"name":"padding"},"link":null},{"localized_name":"upload","name":"upload","type":"IMAGEUPLOAD","widget":{"name":"upload"},"link":null}],"outputs":[{"localized_name":"image","name":"image","type":"IMAGE","links":[447,448]},{"localized_name":"mask","name":"mask","type":"MASK","links":[449]},{"localized_name":"region_top","name":"region_top","type":"INT","links":[450,451,452]},{"localized_name":"region_left","name":"region_left","type":"INT","links":[453,454,455]},{"localized_name":"region_width","name":"region_width","type":"INT","links":[456,457,458]},{"localized_name":"region_height","name":"region_height","type":"INT","links":[459,460,461]}],"properties":{"Node name for S&R":"InpaintRegionEditor","image":"clipspace/clipspace-painted-masked-1772549386614.png [input]"},"widgets_values":["clipspace/clipspace-painted-masked-1772549386614.png [input]",0,"image","{\"x\":70,\"y\":178,\"width\":160,\"height\":311}"]},{"id":30,"type":"ImageScale","pos":[1263.866398796168,419.40170375418995],"size":[270,130],"flags":{},"order":20,"mode":0,"inputs":[{"localized_name":"image","name":"image","type":"IMAGE","link":41},{"localized_name":"upscale_method","name":"upscale_method","type":"COMBO","widget":{"name":"upscale_method"},"link":null},{"localized_name":"width","name":"width","type":"INT","widget":{"name":"width"},"link":458},{"localized_name":"height","name":"height","type":"INT","widget":{"name":"height"},"link":461},{"localized_name":"crop","name":"crop","type":"COMBO","widget":{"name":"crop"},"link":null}],"outputs":[{"localized_name":"IMAGE","name":"IMAGE","type":"IMAGE","links":[52]}],"properties":{"Node name for S&R":"ImageScale"},"widgets_values":["lanczos",512,512,"disabled"]}],"links":[[20,9,0,15,0,"IMAGE"],[21,12,0,16,0,"MASK"],[22,16,0,17,0,"IMAGE"],[23,18,0,17,2,"INT"],[24,18,0,15,2,"INT"],[25,17,0,19,0,"IMAGE"],[26,15,0,20,0,"IMAGE"],[28,20,0,22,0,"LATENT"],[29,19,0,22,1,"MASK"],[31,23,0,25,0,"MODEL"],[32,25,0,26,0,"MODEL"],[33,27,0,26,1,"CONDITIONING"],[34,28,0,26,2,"CONDITIONING"],[35,22,0,26,3,"LATENT"],[36,26,0,29,0,"LATENT"],[37,23,2,29,1,"VAE"],[38,23,1,27,0,"CLIP"],[39,23,1,28,0,"CLIP"],[40,23,2,20,1,"VAE"],[41,29,0,30,0,"IMAGE"],[45,12,0,32,0,"MASK"],[46,9,0,33,0,"IMAGE"],[47,32,0,34,0,"MASK"],[48,34,0,33,1,"IMAGE"],[49,33,0,35,0,"IMAGE"],[51,32,0,36,2,"MASK"],[52,30,0,36,1,"IMAGE"],[56,36,0,37,0,"IMAGE"],[447,64,0,9,0,"IMAGE"],[448,64,0,36,0,"IMAGE"],[449,64,1,12,0,"MASK"],[450,64,2,9,4,"INT"],[451,64,2,12,2,"INT"],[452,64,2,36,4,"INT"],[453,64,3,9,3,"INT"],[454,64,3,12,1,"INT"],[455,64,3,36,3,"INT"],[456,64,4,9,1,"INT"],[457,64,4,12,3,"INT"],[458,64,4,30,2,"INT"],[459,64,5,9,2,"INT"],[460,64,5,12,4,"INT"],[461,64,5,30,3,"INT"]],"groups":[],"config":{},"extra":{"workflowRendererVersion":"LG","ds":{"scale":1.3836906268280942,"offset":[27.354035559090562,-34.994473668655075]}},"version":0.4} \ No newline at end of file