Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9e751a242f | ||
|
|
0e311cf2c6 | ||
|
|
889f08c08b | ||
|
|
5d661b2509 | ||
|
|
be162a2047 | ||
|
|
4ea26ed8de | ||
|
|
c237737420 | ||
|
|
232cf8966c | ||
|
|
96a0618c59 | ||
|
|
d143e83dba | ||
|
|
3dfe98c795 | ||
|
|
c0cc5572d8 |
@@ -35,7 +35,7 @@ jobs:
|
||||
- name: 📦 Building and Bundling wheels
|
||||
shell: bash
|
||||
run: |
|
||||
python -m pip wheel --no-cache-dir --no-deps -r requirements-wheels.txt -w ./wheels 2>&1 | tee build.log
|
||||
python -m pip wheel --no-cache-dir -r requirements-wheels.txt -w ./wheels 2>&1 | tee build.log
|
||||
|
||||
# find source wheels
|
||||
packages=$(cat build.log | awk -F 'Building wheels for collected packages: ' '{print $2}')
|
||||
|
||||
@@ -39,14 +39,20 @@ jobs:
|
||||
- name: 🗑️ Remove files and directories listed in .release_ignore
|
||||
shell: bash
|
||||
run: |
|
||||
if [ -f "${{ env.repo_name }}/.release_ignore" ]; then
|
||||
while IFS= read -r entry; do
|
||||
if [ -f "${{ env.repo_name }}/$entry" ]; then
|
||||
rm "${{ env.repo_name }}/$entry"
|
||||
elif [ -d "${{ env.repo_name }}/$entry" ]; then
|
||||
rm -r "${{ env.repo_name }}/$entry"
|
||||
release_ignore="${{ env.repo_name }}/.release_ignore"
|
||||
if [ -f "$release_ignore" ]; then
|
||||
while IFS= read -r entry || [ -n "$entry" ]; do
|
||||
target="${{ env.repo_name }}/$entry"
|
||||
if [ -e "$target" ]; then
|
||||
if [ -f "$target" ]; then
|
||||
rm "$target"
|
||||
elif [ -d "$target" ]; then
|
||||
rm -r "$target"
|
||||
fi
|
||||
else
|
||||
echo "Warning: $entry does not exist in the repository. Skipping removal."
|
||||
fi
|
||||
done < "${{ env.repo_name }}/.release_ignore"
|
||||
done < "$release_ignore"
|
||||
else
|
||||
echo "No .release_ignore file found. Skipping removal of files and directories."
|
||||
fi
|
||||
|
||||
+2
-1
@@ -1,3 +1,4 @@
|
||||
extern/frame_interpolation/moment.gif
|
||||
extern/frame_interpolation/photos
|
||||
extern/GFPGAN/inputs
|
||||
extern/GFPGAN/inputs
|
||||
.git
|
||||
+14
-17
@@ -1,13 +1,13 @@
|
||||
## MTB Nodes
|
||||
# MTB Nodes
|
||||
|
||||
<a href="https://www.buymeacoffee.com/melmass" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Buy Me A Coffee" style="height: 32px !important;width: 140px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" ></a>
|
||||
|
||||
[** 安装指南**](./INSTALL-CN.md) | [** 示例**](https://github.com/melMass/comfy_mtb/wiki/Examples)
|
||||
|
||||
欢迎使用 MTB Nodes 项目!这个代码库是开放的,您可以自由地探索和利用。它的主要目的是构建用于 [MLOPs](https://github.com/Bismuth-Consultancy-BV/MLOPs) 中的概念验证(POCs)。该项目中的许多节点都是受到现有社区贡献或内置功能的启发而创建的。
|
||||
|
||||
在继续之前,请注意与此项目中使用的某些库相关的许可证。例如,`deepbump` 库采用 [GPLv3](https://github.com/HugoTini/DeepBump/blob/master/LICENSE) 许可证。
|
||||
|
||||
- [MTB Nodes](#mtb-nodes)
|
||||
- [安装](#安装)
|
||||
- [节点列表](#节点列表)
|
||||
- [bbox](#bbox)
|
||||
- [colors](#colors)
|
||||
@@ -20,27 +20,24 @@
|
||||
- [Comfy 资源](#comfy-资源)
|
||||
|
||||
|
||||
## 安装
|
||||
|
||||
- 移至 [INSTALL-CN.md](./INSTALL-CN.md)
|
||||
|
||||
|
||||
## 节点列表
|
||||
# 节点列表
|
||||
|
||||
### bbox
|
||||
## bbox
|
||||
- `Bounding Box`: BBox 构造函数(自定义类型)
|
||||
- `BBox From Mask`: 从遮罩中提取边界框
|
||||
- `Crop`: 根据边界框裁剪图像
|
||||
- `Uncrop`: 根据边界框还原图像
|
||||
|
||||
### colors
|
||||
## colors
|
||||
- `Colored Image`: 给定尺寸的纯色图像
|
||||
- `RGB to HSV`: -
|
||||
- `HSV to RGB`: -
|
||||
- `Color Correct`: 基本颜色校正工具
|
||||
<img src="https://github.com/melMass/comfy_mtb/assets/7041726/7c20ac83-31ff-40ea-a1a0-06c2acefb2ef" width=345/>
|
||||
|
||||
### 人脸检测/交换
|
||||
## 人脸检测/交换
|
||||
- `Face Swap`: 使用 deepinsight/insightface 模型进行人脸交换(该节点在早期版本中称为 `Roop`,功能相同,`Roop` 只是使用这些模型的应用程序)
|
||||
> **注意**
|
||||
> 人脸索引允许您选择要替换的人脸,如下所示:
|
||||
@@ -48,13 +45,13 @@
|
||||
- `Load Face Swap Model`: 加载 insightface 模型用于人脸交换
|
||||
- `Restore Face`: 使用 [GFPGan](https://github.com/TencentARC/GFPGAN) 还原人脸,与 `Face Swap` 配合使用效果很好,并支持 `bg_upscaler` 的 Comfy 原生放大器
|
||||
|
||||
### 图像插值(动画)
|
||||
## 图像插值(动画)
|
||||
- `Load Film Model`: 加载 [FILM](https://github.com/google-research/frame-interpolation) 模型
|
||||
- `Film Interpolation`: 使用 [FILM](https://github.com/google-research/frame-interpolation) 处理输入帧
|
||||
<img src="https://github.com/melMass/comfy_mtb/assets/7041726/3afd1647-6634-4b92-a34b-51432e6a9834" width=400/>
|
||||
- `Export to Prores (experimental)`: 将输入帧导出为 ProRes 4444 mov 文件。这使用 ffmpeg stdin 发送原始的 NumPy 数组,与 `Film Interpolation` 一起使用,目前很简单,但可以进一步扩展。
|
||||
|
||||
### 图像操作
|
||||
## 图像操作
|
||||
- `Blur`: 使用高斯滤波器对图像进行模糊处理。
|
||||
- `Deglaze Image`: 从 [FN16](https://github.com/Fannovel16/FN16-ComfyUI-nodes/blob/main/DeglazeImage.py) 中提取
|
||||
- `Denoise`: 对输入图像进行降噪处理
|
||||
@@ -66,11 +63,11 @@
|
||||
- `Mask To Image`: 将遮罩(Alpha)转换为带有颜色和背景的 RGB 图像
|
||||
- `Save Image Grid`: 将输入批次中的所有图像保存为图像网格。
|
||||
|
||||
### 潜在变量工具
|
||||
## 潜在变量工具
|
||||
- `Latent Lerp`: 两个潜在变量之间的线性插值(混合)
|
||||
|
||||
|
||||
### 其他工具
|
||||
## 其他工具
|
||||
- `Concat Images`: 接受两个图像流,并将它们合并为其他 Comfy 管道支持的图像批次。
|
||||
- `Image Resize Factor`: **已弃用**,因为我后来发现了内
|
||||
|
||||
@@ -84,11 +81,11 @@
|
||||
- `Int to Number`: 用于 WASSuite 数字节点的补充
|
||||
- `Smart Step`: 使用百分比来控制 `KAdvancedSampler` 的步骤(开始/停止)
|
||||
|
||||
### 纹理
|
||||
## 纹理
|
||||
|
||||
- `DeepBump`: 从单张图片生成法线图和高度图
|
||||
|
||||
## Comfy 资源
|
||||
# Comfy 资源
|
||||
|
||||
**指南**:
|
||||
- [官方示例(英文)](https://comfyanonymous.github.io/ComfyUI_examples/)
|
||||
@@ -99,4 +96,4 @@
|
||||
**扩展和自定义节点**:
|
||||
- @WASasquatch 的[Comfy 列表插件(英文)](https://github.com/WASasquatch/comfyui-plugins)
|
||||
|
||||
- [CivitAI 上的 ComfyUI 标签(英文)](https://civitai.com/tag/comfyui)
|
||||
- [CivitAI 上的 ComfyUI 标签(英文)](https://civitai.com/tag/comfyui)
|
||||
|
||||
+14
-19
@@ -1,13 +1,13 @@
|
||||
## MTB Nodes
|
||||
# MTB Nodes
|
||||
|
||||
<a href="https://www.buymeacoffee.com/melmass" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Buy Me A Coffee" style="height: 32px !important;width: 140px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" ></a>
|
||||
|
||||
[**インストールガイド**](./INSTALL-JP.md) | [**サンプル**](https://github.com/melMass/comfy_mtb/wiki/Examples)
|
||||
|
||||
MTB Nodesプロジェクトへようこそ!このコードベースは、自由に探索し、利用することができます。主な目的は、[MLOPs](https://github.com/Bismuth-Consultancy-BV/MLOPs)の実装のための概念実証(POC)を構築することです。このプロジェクトの多くのノードは、既存のコミュニティの貢献や組み込みの機能に触発されています。
|
||||
|
||||
続行する前に、このプロジェクトで使用されている特定のライブラリに関連するライセンスに注意してください。たとえば、「deepbump」ライブラリは、[GPLv3](https://github.com/HugoTini/DeepBump/blob/master/LICENSE)の下でライセンスされています。
|
||||
|
||||
- [MTB Nodes](#mtb-nodes)
|
||||
- [インストール](#インストール)
|
||||
- [ノードリスト](#ノードリスト)
|
||||
- [bbox](#bbox)
|
||||
- [colors](#colors)
|
||||
@@ -20,27 +20,22 @@ MTB Nodesプロジェクトへようこそ!このコードベースは、自
|
||||
- [Comfyリソース](#comfyリソース)
|
||||
|
||||
|
||||
## インストール
|
||||
# ノードリスト
|
||||
|
||||
- [INSTALL-JP.md](./INSTALL-JP.md)に移動しました。
|
||||
|
||||
|
||||
## ノードリスト
|
||||
|
||||
### bbox
|
||||
## bbox
|
||||
- `Bounding Box`: BBoxコンストラクタ(カスタムタイプ)
|
||||
- `BBox From Mask`: マスクからバウンディングボックスを抽出
|
||||
- `Crop`: BBoxから画像を切り抜く
|
||||
- `Uncrop`: BBoxから画像を元に戻す
|
||||
|
||||
### colors
|
||||
## colors
|
||||
- `Colored Image`: 指定されたサイズの一定の色の画像
|
||||
- `RGB to HSV`: -
|
||||
- `HSV to RGB`: -
|
||||
- `Color Correct`: 基本的なカラーコレクションツール
|
||||
<img src="https://github.com/melMass/comfy_mtb/assets/7041726/7c20ac83-31ff-40ea-a1a0-06c2acefb2ef" width=345/>
|
||||
|
||||
### 顔検出 / スワッピング
|
||||
## 顔検出 / スワッピング
|
||||
- `Face Swap`: deepinsight/insightfaceモデルを使用した顔の入れ替え(このノードは初期バージョンでは「Roop」と呼ばれていましたが、同じ機能を提供します。Roopは単にこれらのモデルを使用するアプリです)
|
||||
> **注意**
|
||||
> 顔のインデックスを使用して置き換える顔を選択できます。以下を参照してください:
|
||||
@@ -48,13 +43,13 @@ MTB Nodesプロジェクトへようこそ!このコードベースは、自
|
||||
- `Load Face Swap Model`: 顔の交換のためのinsightfaceモデルを読み込む
|
||||
- `Restore Face`: [GFPGan](https://github.com/TencentARC/GFPGAN)を使用して顔を復元し、`Face Swap`と組み合わせて使用すると非常に効果的であり、`bg_upscaler`のComfyネイティブアップスケーラーもサポートしています。
|
||||
|
||||
### 画像補間(アニメーション)
|
||||
## 画像補間(アニメーション)
|
||||
- `Load Film Model`: [FILM](https://github.com/google-research/frame-interpolation)モデルを読み込む
|
||||
- `Film Interpolation`: [FILM](https://github.com/google-research/frame-interpolation)を使用して入力フレームを処理する
|
||||
<img src="https://github.com/melMass/comfy_mtb/assets/7041726/3afd1647-6634-4b92-a34b-51432e6a9834" width=400/>
|
||||
- `Export to Prores (experimental)`: 入力フレームをProRes 4444 movファイルにエクスポートします。これは現在は単純なものですが、`Film Interpolation`と組み合わせて使用するためのffmpegのstdinを使用して生のNumPy配列を送信するもので、拡張することもできます。
|
||||
|
||||
### 画像操作
|
||||
## 画像操作
|
||||
- `Blur`: ガウスフィルタを使用して画像をぼかす
|
||||
- `Deglaze Image`: [FN16](https://github.com/Fannovel16/FN16-ComfyUI-nodes/blob/main/DeglazeImage.py)から取得
|
||||
- `Denoise`: 入力画像のノイズを除去する
|
||||
@@ -68,10 +63,10 @@ MTB Nodesプロジェクトへようこそ!このコードベースは、自
|
||||
- `Mask To Image`: マスク(アルファ)をカラーと背景を持つRGBイメージに変換します。
|
||||
- `Save Image Grid`: 入力バッチのすべての画像を画像グリッドとして保存します。
|
||||
|
||||
### 潜在的なユーティリティ
|
||||
## 潜在的なユーティリティ
|
||||
- `Latent Lerp`: 2つの潜在的なベクトルの間の線形補間(ブレンド)
|
||||
|
||||
### その他のユーティリティ
|
||||
## その他のユーティリティ
|
||||
- `Concat Images`: 2つの画像ストリームを取り、他のComfyパイプラインでサポートされている画像のバッチとしてマージします。
|
||||
- `Image Resize Factor`: **非推奨**。組み込みの画像リサイズ機能を発見したため、削除される予定です。
|
||||
- `Text To Image`: フォントを使用してテキストを画像に変換するためのユーティリティ
|
||||
@@ -83,11 +78,11 @@ MTB Nodesプロジェクトへようこそ!このコードベースは、自
|
||||
- `Int to Number`: WASSuiteの数値ノードの補完
|
||||
- `Smart Step`: `KAdvancedSampler`のステップ(開始/停止)を制御するための非常に基本的なツールで、パーセンテージを使用します。
|
||||
|
||||
### テクスチャ
|
||||
## テクスチャ
|
||||
|
||||
- `DeepBump`: 1枚の画像から法線マップと高さマップを生成します。
|
||||
|
||||
## Comfyリソース
|
||||
# Comfyリソース
|
||||
|
||||
**ガイド**:
|
||||
- [公式の例(英語)](https://comfyanonymous.github.io/ComfyUI_examples/)
|
||||
@@ -98,4 +93,4 @@ MTB Nodesプロジェクトへようこそ!このコードベースは、自
|
||||
**拡張機能とカスタムノード**:
|
||||
- @WASasquatchによる[Comfyリスト用のプラグイン(英語)](https://github.com/WASasquatch/comfyui-plugins)
|
||||
|
||||
- [CivitAIのComfyUIタグ(英語)](https://civitai.com/tag/comfyui)
|
||||
- [CivitAIのComfyUIタグ(英語)](https://civitai.com/tag/comfyui)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
## MTB Nodes
|
||||
# MTB Nodes
|
||||
<!-- omit in toc -->
|
||||
|
||||
**Translated Readme (using DeepTranslate, PRs are welcome)**:
|
||||

|
||||
@@ -8,12 +9,12 @@
|
||||
|
||||
<a href="https://www.buymeacoffee.com/melmass" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Buy Me A Coffee" style="height: 32px !important;width: 140px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" ></a>
|
||||
|
||||
[**Install Guide**](./INSTALL.md) | [**Examples**](https://github.com/melMass/comfy_mtb/wiki/Examples)
|
||||
|
||||
Welcome to the MTB Nodes project! This codebase is open for you to explore and utilize as you wish. Its primary purpose is to build proof-of-concepts (POCs) for implementation in [MLOPs](https://github.com/Bismuth-Consultancy-BV/MLOPs). Many nodes in this project are inspired by existing community contributions or built-in functionalities.
|
||||
|
||||
Before proceeding, please be aware of the licenses associated with certain libraries used in this project. For example, the `deepbump` library is licensed under [GPLv3](https://github.com/HugoTini/DeepBump/blob/master/LICENSE).
|
||||
|
||||
- [MTB Nodes](#mtb-nodes)
|
||||
- [Installation](#installation)
|
||||
- [Node List](#node-list)
|
||||
- [bbox](#bbox)
|
||||
- [colors](#colors)
|
||||
@@ -26,27 +27,22 @@ Before proceeding, please be aware of the licenses associated with certain libra
|
||||
- [Comfy Resources](#comfy-resources)
|
||||
|
||||
|
||||
## Installation
|
||||
# Node List
|
||||
|
||||
- Moved to [INSTALL.md](./INSTALL.md)
|
||||
|
||||
|
||||
## Node List
|
||||
|
||||
### bbox
|
||||
## bbox
|
||||
- `Bounding Box`: BBox constructor (custom type),
|
||||
- `BBox From Mask`: From a mask extract the bounding box
|
||||
- `Crop`: Crop image from BBox
|
||||
- `Uncrop`: Uncrop image from BBox
|
||||
|
||||
### colors
|
||||
## colors
|
||||
- `Colored Image`: Constant color image of given size
|
||||
- `RGB to HSV`: -,
|
||||
- `HSV to RGB`: -,
|
||||
- `Color Correct`: Basic color correction tools
|
||||
<img src="https://github.com/melMass/comfy_mtb/assets/7041726/7c20ac83-31ff-40ea-a1a0-06c2acefb2ef" width=345/>
|
||||
|
||||
### face detection / swapping
|
||||
## face detection / swapping
|
||||
- `Face Swap`: Face swap using deepinsight/insightface models (this node used to be called `Roop` in early versions, it does the same, roop is *just* an app that uses those model)
|
||||
> **Note**
|
||||
> The face index allow you to choose which face to replace as you can see here:
|
||||
@@ -54,13 +50,13 @@ Before proceeding, please be aware of the licenses associated with certain libra
|
||||
- `Load Face Swap Model`: Load an insightface model for face swapping
|
||||
- `Restore Face`: Using [GFPGan](https://github.com/TencentARC/GFPGAN) to restore faces, works great in conjunction with `Face Swap` and supports Comfy native upscalers for the `bg_upscaler`
|
||||
|
||||
### image interpolation (animation)
|
||||
## image interpolation (animation)
|
||||
- `Load Film Model`: Loads a [FILM](https://github.com/google-research/frame-interpolation) model
|
||||
- `Film Interpolation`: Process input frames using [FILM](https://github.com/google-research/frame-interpolation)
|
||||
<img src="https://github.com/melMass/comfy_mtb/assets/7041726/3afd1647-6634-4b92-a34b-51432e6a9834" width=400/>
|
||||
- `Export to Prores (experimental)`: Exports the input frames to a ProRes 4444 mov file. This is using ffmpeg stdin to send raw numpy arrays, used with `Film Interpolation` and very simple for now but could be expanded upon.
|
||||
|
||||
### image ops
|
||||
## image ops
|
||||
- `Blur`: Blur an image using a Gaussian filter.
|
||||
- `Deglaze Image`: taken from [FN16](https://github.com/Fannovel16/FN16-ComfyUI-nodes/blob/main/DeglazeImage.py),
|
||||
- `Denoise`: Denoise the input image,
|
||||
@@ -72,11 +68,11 @@ Before proceeding, please be aware of the licenses associated with certain libra
|
||||
- `Mask To Image`: Converts a mask (alpha) to an RGB image with a color and background
|
||||
- `Save Image Grid`: Save all the images in the input batch as a grid of images.
|
||||
|
||||
### latent utils
|
||||
## latent utils
|
||||
- `Latent Lerp`: Linear interpolation (blend) between two latent
|
||||
|
||||
|
||||
### misc utils
|
||||
## misc utils
|
||||
- `Concat Images`: Takes two image stream and merge them as a batch of images supported by other Comfy pipelines.
|
||||
- `Image Resize Factor`: **Deprecated**, I since discovered the builtin image resize.
|
||||
- `Text To Image`: Utils to convert text to image using a font
|
||||
@@ -88,11 +84,11 @@ Before proceeding, please be aware of the licenses associated with certain libra
|
||||
- `Int to Number`: Supplement for WASSuite number nodes
|
||||
- `Smart Step`: A very basic tool to control the steps (start/stop) of the `KAdvancedSampler` using percentage
|
||||
|
||||
### textures
|
||||
## textures
|
||||
|
||||
- `DeepBump`: Normal & height maps generation from single pictures
|
||||
|
||||
## Comfy Resources
|
||||
# Comfy Resources
|
||||
|
||||
**Guides**:
|
||||
- [Official Examples (eng)](https://comfyanonymous.github.io/ComfyUI_examples/)
|
||||
|
||||
+111
-103
@@ -5,11 +5,13 @@
|
||||
# Project: comfy_mtb
|
||||
# Author: Mel Massadian
|
||||
# Copyright (c) 2023 Mel Massadian
|
||||
#
|
||||
#
|
||||
###
|
||||
import os
|
||||
|
||||
# todo: don't override this if the user has that setup already
|
||||
os.environ["TF_FORCE_GPU_ALLOW_GROWTH"] = "true"
|
||||
os.environ["TF_GPU_ALLOCATOR"] = "cuda_malloc_async"
|
||||
|
||||
import traceback
|
||||
from .log import log, blue_text, cyan_text, get_summary, get_label
|
||||
@@ -24,7 +26,7 @@ NODE_CLASS_MAPPINGS = {}
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {}
|
||||
NODE_CLASS_MAPPINGS_DEBUG = {}
|
||||
|
||||
__version__ = "0.1.1"
|
||||
__version__ = "0.1.2"
|
||||
|
||||
|
||||
def extract_nodes_from_source(filename):
|
||||
@@ -112,8 +114,16 @@ if web_mtb.exists():
|
||||
|
||||
elif web_extensions_root.exists():
|
||||
web_tgt = here / "web"
|
||||
src = web_tgt.as_posix()
|
||||
dst = web_mtb.as_posix()
|
||||
try:
|
||||
os.symlink(web_tgt.as_posix(), web_mtb.as_posix())
|
||||
if os.name == "nt":
|
||||
import _winapi
|
||||
|
||||
_winapi.CreateJunction(src, dst)
|
||||
else:
|
||||
os.symlink(web_tgt.as_posix(), web_mtb.as_posix())
|
||||
|
||||
except OSError:
|
||||
log.warn(f"Failed to create symlink to {web_mtb}, trying to copy it")
|
||||
try:
|
||||
@@ -174,123 +184,121 @@ from importlib import reload
|
||||
import logging
|
||||
from .endpoint import endlog
|
||||
|
||||
if hasattr(PromptServer, "instance"):
|
||||
|
||||
@PromptServer.instance.routes.get("/mtb/status")
|
||||
async def get_full_library(request):
|
||||
from . import endpoint
|
||||
@PromptServer.instance.routes.get("/mtb/status")
|
||||
async def get_full_library(request):
|
||||
from . import endpoint
|
||||
|
||||
reload(endpoint)
|
||||
reload(endpoint)
|
||||
|
||||
endlog.debug("Getting node registration status")
|
||||
# Check if the request prefers HTML content
|
||||
if "text/html" in request.headers.get("Accept", ""):
|
||||
# # Return an HTML page
|
||||
html_response = endpoint.render_table(
|
||||
NODE_CLASS_MAPPINGS_DEBUG, title="Registered"
|
||||
)
|
||||
html_response += endpoint.render_table(
|
||||
{k: "-" for k in failed}, title="Failed to load"
|
||||
endlog.debug("Getting node registration status")
|
||||
# Check if the request prefers HTML content
|
||||
if "text/html" in request.headers.get("Accept", ""):
|
||||
# # Return an HTML page
|
||||
html_response = endpoint.render_table(
|
||||
NODE_CLASS_MAPPINGS_DEBUG, title="Registered"
|
||||
)
|
||||
html_response += endpoint.render_table(
|
||||
{k: "-" for k in failed}, title="Failed to load"
|
||||
)
|
||||
|
||||
return web.Response(
|
||||
text=endpoint.render_base_template("MTB", html_response),
|
||||
content_type="text/html",
|
||||
)
|
||||
|
||||
return web.json_response(
|
||||
{
|
||||
"registered": NODE_CLASS_MAPPINGS_DEBUG,
|
||||
"failed": failed,
|
||||
}
|
||||
)
|
||||
|
||||
return web.Response(
|
||||
text=endpoint.render_base_template("MTB", html_response),
|
||||
content_type="text/html",
|
||||
@PromptServer.instance.routes.post("/mtb/debug")
|
||||
async def set_debug(request):
|
||||
json_data = await request.json()
|
||||
enabled = json_data.get("enabled")
|
||||
if enabled:
|
||||
os.environ["MTB_DEBUG"] = "true"
|
||||
log.setLevel(logging.DEBUG)
|
||||
log.debug("Debug mode set from API (/mtb/debug POST route)")
|
||||
|
||||
else:
|
||||
if "MTB_DEBUG" in os.environ:
|
||||
# del os.environ["MTB_DEBUG"]
|
||||
os.environ.pop("MTB_DEBUG")
|
||||
log.setLevel(logging.INFO)
|
||||
|
||||
return web.json_response(
|
||||
{"message": f"Debug mode {'set' if enabled else 'unset'}"}
|
||||
)
|
||||
|
||||
return web.json_response(
|
||||
{
|
||||
"registered": NODE_CLASS_MAPPINGS_DEBUG,
|
||||
"failed": failed,
|
||||
}
|
||||
)
|
||||
@PromptServer.instance.routes.get("/mtb")
|
||||
async def get_home(request):
|
||||
from . import endpoint
|
||||
|
||||
reload(endpoint)
|
||||
# Check if the request prefers HTML content
|
||||
if "text/html" in request.headers.get("Accept", ""):
|
||||
# # Return an HTML page
|
||||
html_response = f"""
|
||||
<div class="flex-container menu">
|
||||
<a href="/mtb/debug">debug</a>
|
||||
<a href="/mtb/status">status</a>
|
||||
</div>
|
||||
"""
|
||||
return web.Response(
|
||||
text=endpoint.render_base_template("MTB", html_response),
|
||||
content_type="text/html",
|
||||
)
|
||||
|
||||
@PromptServer.instance.routes.post("/mtb/debug")
|
||||
async def set_debug(request):
|
||||
json_data = await request.json()
|
||||
enabled = json_data.get("enabled")
|
||||
if enabled:
|
||||
os.environ["MTB_DEBUG"] = "true"
|
||||
log.setLevel(logging.DEBUG)
|
||||
log.debug("Debug mode set from API (/mtb/debug POST route)")
|
||||
# Return JSON for other requests
|
||||
return web.json_response({"message": "Welcome to MTB!"})
|
||||
|
||||
else:
|
||||
@PromptServer.instance.routes.get("/mtb/debug")
|
||||
async def get_debug(request):
|
||||
from . import endpoint
|
||||
|
||||
reload(endpoint)
|
||||
enabled = False
|
||||
if "MTB_DEBUG" in os.environ:
|
||||
# del os.environ["MTB_DEBUG"]
|
||||
os.environ.pop("MTB_DEBUG")
|
||||
log.setLevel(logging.INFO)
|
||||
enabled = True
|
||||
# Check if the request prefers HTML content
|
||||
if "text/html" in request.headers.get("Accept", ""):
|
||||
# # Return an HTML page
|
||||
html_response = f"""
|
||||
<h1>MTB Debug Status: {'Enabled' if enabled else 'Disabled'}</h1>
|
||||
"""
|
||||
return web.Response(
|
||||
text=endpoint.render_base_template("Debug", html_response),
|
||||
content_type="text/html",
|
||||
)
|
||||
|
||||
return web.json_response({"message": f"Debug mode {'set' if enabled else 'unset'}"})
|
||||
# Return JSON for other requests
|
||||
return web.json_response({"enabled": enabled})
|
||||
|
||||
@PromptServer.instance.routes.get("/mtb/actions")
|
||||
async def no_route(request):
|
||||
from . import endpoint
|
||||
|
||||
@PromptServer.instance.routes.get("/mtb")
|
||||
async def get_home(request):
|
||||
from . import endpoint
|
||||
if "text/html" in request.headers.get("Accept", ""):
|
||||
html_response = f"""
|
||||
<h1>Actions has no get for now...</h1>
|
||||
"""
|
||||
return web.Response(
|
||||
text=endpoint.render_base_template("Actions", html_response),
|
||||
content_type="text/html",
|
||||
)
|
||||
return web.json_response({"message": "actions has no get for now"})
|
||||
|
||||
reload(endpoint)
|
||||
# Check if the request prefers HTML content
|
||||
if "text/html" in request.headers.get("Accept", ""):
|
||||
# # Return an HTML page
|
||||
html_response = f"""
|
||||
<div class="flex-container menu">
|
||||
<a href="/mtb/debug">debug</a>
|
||||
<a href="/mtb/status">status</a>
|
||||
</div>
|
||||
"""
|
||||
return web.Response(
|
||||
text=endpoint.render_base_template("MTB", html_response),
|
||||
content_type="text/html",
|
||||
)
|
||||
@PromptServer.instance.routes.post("/mtb/actions")
|
||||
async def do_action(request):
|
||||
from . import endpoint
|
||||
|
||||
# Return JSON for other requests
|
||||
return web.json_response({"message": "Welcome to MTB!"})
|
||||
reload(endpoint)
|
||||
|
||||
|
||||
@PromptServer.instance.routes.get("/mtb/debug")
|
||||
async def get_debug(request):
|
||||
from . import endpoint
|
||||
|
||||
reload(endpoint)
|
||||
enabled = False
|
||||
if "MTB_DEBUG" in os.environ:
|
||||
enabled = True
|
||||
# Check if the request prefers HTML content
|
||||
if "text/html" in request.headers.get("Accept", ""):
|
||||
# # Return an HTML page
|
||||
html_response = f"""
|
||||
<h1>MTB Debug Status: {'Enabled' if enabled else 'Disabled'}</h1>
|
||||
"""
|
||||
return web.Response(
|
||||
text=endpoint.render_base_template("Debug", html_response),
|
||||
content_type="text/html",
|
||||
)
|
||||
|
||||
# Return JSON for other requests
|
||||
return web.json_response({"enabled": enabled})
|
||||
|
||||
|
||||
@PromptServer.instance.routes.get("/mtb/actions")
|
||||
async def no_route(request):
|
||||
from . import endpoint
|
||||
|
||||
if "text/html" in request.headers.get("Accept", ""):
|
||||
html_response = f"""
|
||||
<h1>Actions has no get for now...</h1>
|
||||
"""
|
||||
return web.Response(
|
||||
text=endpoint.render_base_template("Actions", html_response),
|
||||
content_type="text/html",
|
||||
)
|
||||
return web.json_response({"message": "actions has no get for now"})
|
||||
|
||||
|
||||
@PromptServer.instance.routes.post("/mtb/actions")
|
||||
async def do_action(request):
|
||||
from . import endpoint
|
||||
|
||||
reload(endpoint)
|
||||
|
||||
return await endpoint.do_action(request)
|
||||
return await endpoint.do_action(request)
|
||||
|
||||
|
||||
# - WAS Dictionary
|
||||
|
||||
+274
-237
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"last_node_id": 76,
|
||||
"last_link_id": 161,
|
||||
"last_node_id": 86,
|
||||
"last_link_id": 178,
|
||||
"nodes": [
|
||||
{
|
||||
"id": 59,
|
||||
@@ -14,7 +14,7 @@
|
||||
26
|
||||
],
|
||||
"flags": {},
|
||||
"order": 12,
|
||||
"order": 13,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
@@ -50,7 +50,7 @@
|
||||
26
|
||||
],
|
||||
"flags": {},
|
||||
"order": 8,
|
||||
"order": 9,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
@@ -85,7 +85,7 @@
|
||||
26
|
||||
],
|
||||
"flags": {},
|
||||
"order": 11,
|
||||
"order": 12,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
@@ -121,7 +121,7 @@
|
||||
26
|
||||
],
|
||||
"flags": {},
|
||||
"order": 6,
|
||||
"order": 7,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
@@ -167,7 +167,7 @@
|
||||
{
|
||||
"name": "text",
|
||||
"type": "STRING",
|
||||
"link": 87,
|
||||
"link": 164,
|
||||
"widget": {
|
||||
"name": "text",
|
||||
"config": [
|
||||
@@ -242,7 +242,7 @@
|
||||
164.31304931640625
|
||||
],
|
||||
"flags": {},
|
||||
"order": 7,
|
||||
"order": 8,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
@@ -316,6 +316,114 @@
|
||||
"revAnimated_v122.safetensors"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 25,
|
||||
"type": "PreviewImage",
|
||||
"pos": [
|
||||
2338.9229387812507,
|
||||
-632.8275743593749
|
||||
],
|
||||
"size": [
|
||||
726.28564453125,
|
||||
475.3432312011719
|
||||
],
|
||||
"flags": {},
|
||||
"order": 20,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "images",
|
||||
"type": "IMAGE",
|
||||
"link": 150
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "PreviewImage"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 75,
|
||||
"type": "PreviewImage",
|
||||
"pos": [
|
||||
1573.5946044921875,
|
||||
-629.80322265625
|
||||
],
|
||||
"size": [
|
||||
691.7459716796875,
|
||||
479.6098327636719
|
||||
],
|
||||
"flags": {},
|
||||
"order": 19,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "images",
|
||||
"type": "IMAGE",
|
||||
"link": 169
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "PreviewImage"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 73,
|
||||
"type": "PreviewImage",
|
||||
"pos": [
|
||||
760,
|
||||
-630
|
||||
],
|
||||
"size": [
|
||||
671.1859741210938,
|
||||
483.1548156738281
|
||||
],
|
||||
"flags": {},
|
||||
"order": 16,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "images",
|
||||
"type": "IMAGE",
|
||||
"link": 153
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "PreviewImage"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 79,
|
||||
"type": "Text box",
|
||||
"pos": [
|
||||
-1400,
|
||||
276
|
||||
],
|
||||
"size": [
|
||||
400,
|
||||
200
|
||||
],
|
||||
"flags": {},
|
||||
"order": 2,
|
||||
"mode": 0,
|
||||
"outputs": [
|
||||
{
|
||||
"name": "STRING",
|
||||
"type": "STRING",
|
||||
"links": [
|
||||
164
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 0
|
||||
}
|
||||
],
|
||||
"title": "❌Mel Negatives (general) (Negative)",
|
||||
"properties": {
|
||||
"Node name for S&R": "Text box"
|
||||
},
|
||||
"widgets_values": [
|
||||
"embedding:EasyNegative, embedding:EasyNegativeV2, watermark, text, deformed, disfigured, blurry"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"type": "KSampler",
|
||||
@@ -328,7 +436,7 @@
|
||||
474
|
||||
],
|
||||
"flags": {},
|
||||
"order": 13,
|
||||
"order": 14,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
@@ -366,7 +474,7 @@
|
||||
"Node name for S&R": "KSampler"
|
||||
},
|
||||
"widgets_values": [
|
||||
542821171532982,
|
||||
542821171533322,
|
||||
"fixed",
|
||||
45,
|
||||
8,
|
||||
@@ -389,7 +497,7 @@
|
||||
"flags": {
|
||||
"collapsed": false
|
||||
},
|
||||
"order": 14,
|
||||
"order": 15,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
@@ -410,7 +518,7 @@
|
||||
"type": "IMAGE",
|
||||
"links": [
|
||||
153,
|
||||
161
|
||||
167
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 0
|
||||
@@ -421,74 +529,24 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 25,
|
||||
"type": "PreviewImage",
|
||||
"id": 70,
|
||||
"type": "Restore Face (mtb)",
|
||||
"pos": [
|
||||
2338.9229387812507,
|
||||
-632.8275743593749
|
||||
2320,
|
||||
-50
|
||||
],
|
||||
"size": [
|
||||
726.28564453125,
|
||||
475.3432312011719
|
||||
],
|
||||
"flags": {},
|
||||
"order": 19,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "images",
|
||||
"type": "IMAGE",
|
||||
"link": 150
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "PreviewImage"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 75,
|
||||
"type": "PreviewImage",
|
||||
"pos": [
|
||||
1573.5946044921875,
|
||||
-629.80322265625
|
||||
],
|
||||
"size": [
|
||||
691.7459716796875,
|
||||
479.6098327636719
|
||||
315,
|
||||
186
|
||||
],
|
||||
"flags": {},
|
||||
"order": 18,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "images",
|
||||
"type": "IMAGE",
|
||||
"link": 156
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "PreviewImage"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 70,
|
||||
"type": "Restore Face (mtb)",
|
||||
"pos": [
|
||||
1899,
|
||||
-51
|
||||
],
|
||||
"size": [
|
||||
315,
|
||||
150
|
||||
],
|
||||
"flags": {},
|
||||
"order": 17,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "image",
|
||||
"type": "IMAGE",
|
||||
"link": 149
|
||||
"link": 168
|
||||
},
|
||||
{
|
||||
"name": "model",
|
||||
@@ -512,78 +570,56 @@
|
||||
"Node name for S&R": "Restore Face (mtb)"
|
||||
},
|
||||
"widgets_values": [
|
||||
"false",
|
||||
"false",
|
||||
false,
|
||||
false,
|
||||
0.5,
|
||||
"true"
|
||||
true
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 67,
|
||||
"type": "Face Swap (mtb)",
|
||||
"id": 72,
|
||||
"type": "UpscaleModelLoader",
|
||||
"pos": [
|
||||
1127,
|
||||
-26
|
||||
1715,
|
||||
52
|
||||
],
|
||||
"size": [
|
||||
315,
|
||||
122
|
||||
260.3902351585391,
|
||||
58
|
||||
],
|
||||
"flags": {},
|
||||
"order": 16,
|
||||
"order": 3,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "image",
|
||||
"type": "IMAGE",
|
||||
"link": 161
|
||||
},
|
||||
{
|
||||
"name": "reference",
|
||||
"type": "IMAGE",
|
||||
"link": 160,
|
||||
"slot_index": 1
|
||||
},
|
||||
{
|
||||
"name": "faceswap_model",
|
||||
"type": "FACESWAP_MODEL",
|
||||
"link": 147,
|
||||
"slot_index": 2
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "IMAGE",
|
||||
"type": "IMAGE",
|
||||
"name": "UPSCALE_MODEL",
|
||||
"type": "UPSCALE_MODEL",
|
||||
"links": [
|
||||
149,
|
||||
156
|
||||
152
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 0
|
||||
"shape": 3
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "Face Swap (mtb)"
|
||||
"Node name for S&R": "UpscaleModelLoader"
|
||||
},
|
||||
"widgets_values": [
|
||||
"0",
|
||||
"false"
|
||||
"4x-UltraSharp.pth"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 71,
|
||||
"type": "Load Face Enhance Model (mtb)",
|
||||
"pos": [
|
||||
1476,
|
||||
240
|
||||
2005,
|
||||
40
|
||||
],
|
||||
"size": [
|
||||
315,
|
||||
82
|
||||
265.97600515853924,
|
||||
87.31192548828142
|
||||
],
|
||||
"flags": {},
|
||||
"order": 9,
|
||||
"order": 11,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
@@ -611,82 +647,26 @@
|
||||
2
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 72,
|
||||
"type": "UpscaleModelLoader",
|
||||
"pos": [
|
||||
1110,
|
||||
241
|
||||
],
|
||||
"size": [
|
||||
315,
|
||||
58
|
||||
],
|
||||
"flags": {},
|
||||
"order": 2,
|
||||
"mode": 0,
|
||||
"outputs": [
|
||||
{
|
||||
"name": "UPSCALE_MODEL",
|
||||
"type": "UPSCALE_MODEL",
|
||||
"links": [
|
||||
152
|
||||
],
|
||||
"shape": 3
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "UpscaleModelLoader"
|
||||
},
|
||||
"widgets_values": [
|
||||
"4x-UltraSharp.pth"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 73,
|
||||
"type": "PreviewImage",
|
||||
"pos": [
|
||||
760,
|
||||
-630
|
||||
],
|
||||
"size": [
|
||||
671.1859741210938,
|
||||
483.1548156738281
|
||||
],
|
||||
"flags": {},
|
||||
"order": 15,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "images",
|
||||
"type": "IMAGE",
|
||||
"link": 153
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "PreviewImage"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 76,
|
||||
"type": "Load Image From Url (mtb)",
|
||||
"pos": [
|
||||
161,
|
||||
231
|
||||
624,
|
||||
39
|
||||
],
|
||||
"size": [
|
||||
315,
|
||||
58
|
||||
],
|
||||
"flags": {},
|
||||
"order": 3,
|
||||
"order": 4,
|
||||
"mode": 0,
|
||||
"outputs": [
|
||||
{
|
||||
"name": "IMAGE",
|
||||
"type": "IMAGE",
|
||||
"links": [
|
||||
160
|
||||
166
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 0
|
||||
@@ -703,22 +683,22 @@
|
||||
"id": 69,
|
||||
"type": "Load Face Swap Model (mtb)",
|
||||
"pos": [
|
||||
172,
|
||||
503
|
||||
621,
|
||||
252
|
||||
],
|
||||
"size": [
|
||||
315,
|
||||
58
|
||||
],
|
||||
"flags": {},
|
||||
"order": 4,
|
||||
"order": 5,
|
||||
"mode": 0,
|
||||
"outputs": [
|
||||
{
|
||||
"name": "FACESWAP_MODEL",
|
||||
"type": "FACESWAP_MODEL",
|
||||
"links": [
|
||||
147
|
||||
165
|
||||
],
|
||||
"shape": 3
|
||||
}
|
||||
@@ -731,43 +711,92 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"type": "Styles Loader (mtb)",
|
||||
"id": 81,
|
||||
"type": "Load Face Analysis Model (mtb)",
|
||||
"pos": [
|
||||
-1341,
|
||||
276
|
||||
624,
|
||||
144
|
||||
],
|
||||
"size": [
|
||||
315,
|
||||
78
|
||||
58
|
||||
],
|
||||
"flags": {
|
||||
"collapsed": false
|
||||
},
|
||||
"order": 5,
|
||||
"flags": {},
|
||||
"order": 6,
|
||||
"mode": 0,
|
||||
"outputs": [
|
||||
{
|
||||
"name": "positive",
|
||||
"type": "STRING",
|
||||
"links": [],
|
||||
"shape": 3
|
||||
},
|
||||
{
|
||||
"name": "negative",
|
||||
"type": "STRING",
|
||||
"name": "FACE_ANALYSIS_MODEL",
|
||||
"type": "FACE_ANALYSIS_MODEL",
|
||||
"links": [
|
||||
87
|
||||
170
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 1
|
||||
"shape": 3
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "Styles Loader (mtb)"
|
||||
"Node name for S&R": "Load Face Analysis Model (mtb)"
|
||||
},
|
||||
"widgets_values": [
|
||||
"❌Low Token"
|
||||
"buffalo_l"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 80,
|
||||
"type": "Face Swap (mtb)",
|
||||
"pos": [
|
||||
1255,
|
||||
-32
|
||||
],
|
||||
"size": [
|
||||
210,
|
||||
154
|
||||
],
|
||||
"flags": {},
|
||||
"order": 17,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "image",
|
||||
"type": "IMAGE",
|
||||
"link": 167
|
||||
},
|
||||
{
|
||||
"name": "reference",
|
||||
"type": "IMAGE",
|
||||
"link": 166
|
||||
},
|
||||
{
|
||||
"name": "faceanalysis_model",
|
||||
"type": "FACE_ANALYSIS_MODEL",
|
||||
"link": 170,
|
||||
"slot_index": 2
|
||||
},
|
||||
{
|
||||
"name": "faceswap_model",
|
||||
"type": "FACESWAP_MODEL",
|
||||
"link": 165,
|
||||
"slot_index": 3
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "IMAGE",
|
||||
"type": "IMAGE",
|
||||
"links": [
|
||||
168,
|
||||
169
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 0
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "Face Swap (mtb)"
|
||||
},
|
||||
"widgets_values": [
|
||||
"0",
|
||||
false
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -796,14 +825,6 @@
|
||||
2,
|
||||
"CONDITIONING"
|
||||
],
|
||||
[
|
||||
87,
|
||||
20,
|
||||
1,
|
||||
7,
|
||||
1,
|
||||
"STRING"
|
||||
],
|
||||
[
|
||||
117,
|
||||
16,
|
||||
@@ -876,22 +897,6 @@
|
||||
0,
|
||||
"CLIP"
|
||||
],
|
||||
[
|
||||
147,
|
||||
69,
|
||||
0,
|
||||
67,
|
||||
2,
|
||||
"FACESWAP_MODEL"
|
||||
],
|
||||
[
|
||||
149,
|
||||
67,
|
||||
0,
|
||||
70,
|
||||
0,
|
||||
"IMAGE"
|
||||
],
|
||||
[
|
||||
150,
|
||||
70,
|
||||
@@ -925,28 +930,60 @@
|
||||
"IMAGE"
|
||||
],
|
||||
[
|
||||
156,
|
||||
67,
|
||||
164,
|
||||
79,
|
||||
0,
|
||||
7,
|
||||
1,
|
||||
"STRING"
|
||||
],
|
||||
[
|
||||
165,
|
||||
69,
|
||||
0,
|
||||
80,
|
||||
3,
|
||||
"FACESWAP_MODEL"
|
||||
],
|
||||
[
|
||||
166,
|
||||
76,
|
||||
0,
|
||||
80,
|
||||
1,
|
||||
"IMAGE"
|
||||
],
|
||||
[
|
||||
167,
|
||||
66,
|
||||
0,
|
||||
80,
|
||||
0,
|
||||
"IMAGE"
|
||||
],
|
||||
[
|
||||
168,
|
||||
80,
|
||||
0,
|
||||
70,
|
||||
0,
|
||||
"IMAGE"
|
||||
],
|
||||
[
|
||||
169,
|
||||
80,
|
||||
0,
|
||||
75,
|
||||
0,
|
||||
"IMAGE"
|
||||
],
|
||||
[
|
||||
160,
|
||||
76,
|
||||
170,
|
||||
81,
|
||||
0,
|
||||
67,
|
||||
1,
|
||||
"IMAGE"
|
||||
],
|
||||
[
|
||||
161,
|
||||
66,
|
||||
0,
|
||||
67,
|
||||
0,
|
||||
"IMAGE"
|
||||
80,
|
||||
2,
|
||||
"FACE_ANALYSIS_MODEL"
|
||||
]
|
||||
],
|
||||
"groups": [
|
||||
|
||||
+436
-412
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"last_node_id": 39,
|
||||
"last_node_id": 42,
|
||||
"last_link_id": 69,
|
||||
"nodes": [
|
||||
{
|
||||
@@ -93,7 +93,7 @@
|
||||
],
|
||||
"size": [
|
||||
210,
|
||||
36.36605696244669
|
||||
36.366058349609375
|
||||
],
|
||||
"flags": {},
|
||||
"order": 8,
|
||||
@@ -347,7 +347,7 @@
|
||||
114
|
||||
],
|
||||
"size": [
|
||||
301.23302978515596,
|
||||
301.2330322265625,
|
||||
98
|
||||
],
|
||||
"flags": {},
|
||||
@@ -469,7 +469,7 @@
|
||||
"Node name for S&R": "CLIPTextEncode"
|
||||
},
|
||||
"widgets_values": [
|
||||
"A blonde doll with a pink dress sleeping, draping, wrinkles"
|
||||
"A plastic Barbie doll with a pink dress sleeping, draping, wrinkles, shiny"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -481,7 +481,7 @@
|
||||
],
|
||||
"size": [
|
||||
294,
|
||||
95.12843764123829
|
||||
95.1284408569336
|
||||
],
|
||||
"flags": {},
|
||||
"order": 3,
|
||||
@@ -502,7 +502,7 @@
|
||||
"Node name for S&R": "Text box"
|
||||
},
|
||||
"widgets_values": [
|
||||
"embedding:EasyNegative, embedding:EasyNegativeV2, watermark, text, deformed"
|
||||
"embedding:EasyNegative, embedding:EasyNegativeV2, watermark, text, deformed, NSFW, Cleavage, Pubic Hair, Nudity, Naked, censored"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -690,8 +690,8 @@
|
||||
259
|
||||
],
|
||||
"size": [
|
||||
330.11123461913985,
|
||||
378.1239961059566
|
||||
330.1112365722656,
|
||||
378.1239929199219
|
||||
],
|
||||
"flags": {},
|
||||
"order": 19,
|
||||
@@ -716,8 +716,8 @@
|
||||
1256
|
||||
],
|
||||
"size": [
|
||||
356.17758847656205,
|
||||
471.87858076171824
|
||||
356.1775817871094,
|
||||
471.8785705566406
|
||||
],
|
||||
"flags": {},
|
||||
"order": 14,
|
||||
@@ -735,8 +735,7 @@
|
||||
"widgets_values": [
|
||||
12,
|
||||
1,
|
||||
true,
|
||||
"/view?filename=7964e7cc8b.gif&subfolder=&type=output"
|
||||
true
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -833,7 +832,7 @@
|
||||
882
|
||||
],
|
||||
"size": [
|
||||
232.28509687500036,
|
||||
232.28509521484375,
|
||||
166
|
||||
],
|
||||
"flags": {},
|
||||
@@ -873,12 +872,12 @@
|
||||
"id": 17,
|
||||
"type": "Animation Builder (mtb)",
|
||||
"pos": [
|
||||
-1309,
|
||||
-1310,
|
||||
883
|
||||
],
|
||||
"size": [
|
||||
211.60000610351562,
|
||||
294
|
||||
318
|
||||
],
|
||||
"flags": {},
|
||||
"order": 7,
|
||||
@@ -1175,8 +1174,8 @@
|
||||
{
|
||||
"title": "START THE QUEUE BY CLICKLING HERE 👆",
|
||||
"bounding": [
|
||||
-1611,
|
||||
1196,
|
||||
-1612,
|
||||
1219,
|
||||
521,
|
||||
80
|
||||
],
|
||||
|
||||
@@ -1,932 +0,0 @@
|
||||
{
|
||||
"last_node_id": 24,
|
||||
"last_link_id": 30,
|
||||
"nodes": [
|
||||
{
|
||||
"id": 11,
|
||||
"type": "Get Batch From History (mtb)",
|
||||
"pos": [
|
||||
-828,
|
||||
522
|
||||
],
|
||||
"size": [
|
||||
235.1999969482422,
|
||||
118
|
||||
],
|
||||
"flags": {},
|
||||
"order": 12,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "passthrough_image",
|
||||
"type": "IMAGE",
|
||||
"link": 10
|
||||
},
|
||||
{
|
||||
"name": "enable",
|
||||
"type": "BOOL",
|
||||
"link": 9,
|
||||
"widget": {
|
||||
"name": "enable",
|
||||
"config": [
|
||||
"BOOL",
|
||||
{
|
||||
"default": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"slot_index": 1
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "i",
|
||||
"type": "IMAGE",
|
||||
"links": [
|
||||
26
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 0
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "Get Batch From History (mtb)"
|
||||
},
|
||||
"widgets_values": [
|
||||
false,
|
||||
1,
|
||||
0
|
||||
],
|
||||
"color": "#223",
|
||||
"bgcolor": "#335"
|
||||
},
|
||||
{
|
||||
"id": 24,
|
||||
"type": "Note",
|
||||
"pos": [
|
||||
-827,
|
||||
406
|
||||
],
|
||||
"size": [
|
||||
229.35427033319013,
|
||||
69.73426380916959
|
||||
],
|
||||
"flags": {},
|
||||
"order": 5,
|
||||
"mode": 0,
|
||||
"properties": {
|
||||
"text": ""
|
||||
},
|
||||
"widgets_values": [
|
||||
"On first frame we get the init image, on all subsequent ones the feedback from the previous queue item"
|
||||
],
|
||||
"color": "#223",
|
||||
"bgcolor": "#335",
|
||||
"shape": 1
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"type": "LoadImage",
|
||||
"pos": [
|
||||
-1388,
|
||||
321
|
||||
],
|
||||
"size": [
|
||||
315,
|
||||
314
|
||||
],
|
||||
"flags": {},
|
||||
"order": 4,
|
||||
"mode": 0,
|
||||
"outputs": [
|
||||
{
|
||||
"name": "IMAGE",
|
||||
"type": "IMAGE",
|
||||
"links": [
|
||||
10
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 0
|
||||
},
|
||||
{
|
||||
"name": "MASK",
|
||||
"type": "MASK",
|
||||
"links": null,
|
||||
"shape": 3
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "LoadImage"
|
||||
},
|
||||
"widgets_values": [
|
||||
"example.png",
|
||||
"image"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"type": "PrimitiveNode",
|
||||
"pos": [
|
||||
-1679,
|
||||
817
|
||||
],
|
||||
"size": [
|
||||
210,
|
||||
82
|
||||
],
|
||||
"flags": {},
|
||||
"order": 3,
|
||||
"mode": 0,
|
||||
"outputs": [
|
||||
{
|
||||
"name": "INT",
|
||||
"type": "INT",
|
||||
"links": [
|
||||
8
|
||||
],
|
||||
"widget": {
|
||||
"name": "int",
|
||||
"config": [
|
||||
"INT",
|
||||
{
|
||||
"default": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "int",
|
||||
"properties": {},
|
||||
"widgets_values": [
|
||||
0,
|
||||
"increment"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"type": "Int To Bool (mtb)",
|
||||
"pos": [
|
||||
-1290,
|
||||
818
|
||||
],
|
||||
"size": [
|
||||
210,
|
||||
42.2801628112793
|
||||
],
|
||||
"flags": {},
|
||||
"order": 9,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "int",
|
||||
"type": "INT",
|
||||
"link": 8,
|
||||
"widget": {
|
||||
"name": "int",
|
||||
"config": [
|
||||
"INT",
|
||||
{
|
||||
"default": 0
|
||||
}
|
||||
]
|
||||
},
|
||||
"slot_index": 0
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "BOOL",
|
||||
"type": "BOOL",
|
||||
"links": [
|
||||
9
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 0
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "Int To Bool (mtb)"
|
||||
},
|
||||
"widgets_values": [
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"type": "Transform Image (mtb)",
|
||||
"pos": [
|
||||
-54,
|
||||
515
|
||||
],
|
||||
"size": [
|
||||
315,
|
||||
154
|
||||
],
|
||||
"flags": {},
|
||||
"order": 13,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "image",
|
||||
"type": "IMAGE",
|
||||
"link": 26
|
||||
},
|
||||
{
|
||||
"name": "angle",
|
||||
"type": "FLOAT",
|
||||
"link": 30,
|
||||
"widget": {
|
||||
"name": "angle",
|
||||
"config": [
|
||||
"FLOAT",
|
||||
{
|
||||
"default": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "IMAGE",
|
||||
"type": "IMAGE",
|
||||
"links": [
|
||||
24
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 0
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "Transform Image (mtb)"
|
||||
},
|
||||
"widgets_values": [
|
||||
0,
|
||||
5,
|
||||
1.02,
|
||||
0,
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"type": "Export To Prores (mtb)",
|
||||
"pos": [
|
||||
394,
|
||||
1803
|
||||
],
|
||||
"size": [
|
||||
315,
|
||||
82
|
||||
],
|
||||
"flags": {},
|
||||
"order": 10,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "images",
|
||||
"type": "IMAGE",
|
||||
"link": 17
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "VIDEO",
|
||||
"type": "VIDEO",
|
||||
"links": null,
|
||||
"shape": 3
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "Export To Prores (mtb)"
|
||||
},
|
||||
"widgets_values": [
|
||||
12,
|
||||
"export"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"type": "Save Gif (mtb)",
|
||||
"pos": [
|
||||
392,
|
||||
1321
|
||||
],
|
||||
"size": [
|
||||
210,
|
||||
336
|
||||
],
|
||||
"flags": {},
|
||||
"order": 11,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "image",
|
||||
"type": "IMAGE",
|
||||
"link": 18
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "Save Gif (mtb)"
|
||||
},
|
||||
"widgets_values": [
|
||||
12,
|
||||
1,
|
||||
true,
|
||||
"/view?filename=8b62123f3c.gif&subfolder=&type=output"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"type": "Styles Loader (mtb)",
|
||||
"pos": [
|
||||
72,
|
||||
213
|
||||
],
|
||||
"size": [
|
||||
315,
|
||||
78
|
||||
],
|
||||
"flags": {},
|
||||
"order": 1,
|
||||
"mode": 0,
|
||||
"outputs": [
|
||||
{
|
||||
"name": "positive",
|
||||
"type": "STRING",
|
||||
"links": null,
|
||||
"shape": 3
|
||||
},
|
||||
{
|
||||
"name": "negative",
|
||||
"type": "STRING",
|
||||
"links": [
|
||||
15
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 1
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "Styles Loader (mtb)"
|
||||
},
|
||||
"widgets_values": [
|
||||
"❌Low Token"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"type": "CheckpointLoaderSimple",
|
||||
"pos": [
|
||||
64,
|
||||
68
|
||||
],
|
||||
"size": [
|
||||
315,
|
||||
98
|
||||
],
|
||||
"flags": {},
|
||||
"order": 0,
|
||||
"mode": 0,
|
||||
"outputs": [
|
||||
{
|
||||
"name": "MODEL",
|
||||
"type": "MODEL",
|
||||
"links": [
|
||||
4
|
||||
],
|
||||
"shape": 3
|
||||
},
|
||||
{
|
||||
"name": "CLIP",
|
||||
"type": "CLIP",
|
||||
"links": [
|
||||
5
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 1
|
||||
},
|
||||
{
|
||||
"name": "VAE",
|
||||
"type": "VAE",
|
||||
"links": [
|
||||
6
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 2
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "CheckpointLoaderSimple"
|
||||
},
|
||||
"widgets_values": [
|
||||
"revAnimated_v122.safetensors"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"type": "Fit Number (mtb)",
|
||||
"pos": [
|
||||
39,
|
||||
842
|
||||
],
|
||||
"size": [
|
||||
210,
|
||||
166
|
||||
],
|
||||
"flags": {},
|
||||
"order": 6,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "value",
|
||||
"type": "FLOAT",
|
||||
"link": 27
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "FLOAT",
|
||||
"type": "FLOAT",
|
||||
"links": [
|
||||
28
|
||||
],
|
||||
"shape": 3
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "Fit Number (mtb)"
|
||||
},
|
||||
"widgets_values": [
|
||||
true,
|
||||
0,
|
||||
1,
|
||||
0.9,
|
||||
0.2
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 23,
|
||||
"type": "Fit Number (mtb)",
|
||||
"pos": [
|
||||
-342,
|
||||
621
|
||||
],
|
||||
"size": [
|
||||
210,
|
||||
166
|
||||
],
|
||||
"flags": {},
|
||||
"order": 7,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "value",
|
||||
"type": "FLOAT",
|
||||
"link": 29
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "FLOAT",
|
||||
"type": "FLOAT",
|
||||
"links": [
|
||||
30
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 0
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "Fit Number (mtb)"
|
||||
},
|
||||
"widgets_values": [
|
||||
true,
|
||||
0.7,
|
||||
1,
|
||||
0,
|
||||
3
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"type": "## i2i [cac944]",
|
||||
"pos": [
|
||||
567,
|
||||
65
|
||||
],
|
||||
"size": [
|
||||
400,
|
||||
230
|
||||
],
|
||||
"flags": {},
|
||||
"order": 14,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "model",
|
||||
"type": "MODEL",
|
||||
"link": 4,
|
||||
"slot_index": 0
|
||||
},
|
||||
{
|
||||
"name": "clip",
|
||||
"type": "CLIP",
|
||||
"link": 5
|
||||
},
|
||||
{
|
||||
"name": "vae",
|
||||
"type": "VAE",
|
||||
"link": 6
|
||||
},
|
||||
{
|
||||
"name": "image",
|
||||
"type": "IMAGE",
|
||||
"link": 24
|
||||
},
|
||||
{
|
||||
"name": "negative",
|
||||
"type": "STRING",
|
||||
"link": 15,
|
||||
"widget": {
|
||||
"name": "negative",
|
||||
"config": [
|
||||
"STRING",
|
||||
{
|
||||
"multiline": true,
|
||||
"placeholder": "negative",
|
||||
"default": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
"slot_index": 4
|
||||
},
|
||||
{
|
||||
"name": "denoise",
|
||||
"type": "FLOAT",
|
||||
"link": 28,
|
||||
"widget": {
|
||||
"name": "denoise",
|
||||
"config": [
|
||||
"FLOAT",
|
||||
{
|
||||
"default": 0.6,
|
||||
"min": 0,
|
||||
"max": 1,
|
||||
"step": 0.01
|
||||
}
|
||||
]
|
||||
},
|
||||
"slot_index": 5
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "IMAGE",
|
||||
"type": "IMAGE",
|
||||
"links": [
|
||||
25
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 0
|
||||
},
|
||||
{
|
||||
"name": "LATENT",
|
||||
"type": "LATENT",
|
||||
"links": null,
|
||||
"shape": 3
|
||||
}
|
||||
],
|
||||
"title": "## i2i",
|
||||
"properties": {
|
||||
"Node name for S&R": "## i2i [cac944]"
|
||||
},
|
||||
"widgets_values": [
|
||||
"A blond girl in a pink dress, clear sky, 1958",
|
||||
"",
|
||||
0.2599999999999997
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"type": "SaveImage",
|
||||
"pos": [
|
||||
1054,
|
||||
67
|
||||
],
|
||||
"size": [
|
||||
1110.1168110198978,
|
||||
630.0240418701173
|
||||
],
|
||||
"flags": {},
|
||||
"order": 15,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "images",
|
||||
"type": "IMAGE",
|
||||
"link": 25
|
||||
}
|
||||
],
|
||||
"properties": {},
|
||||
"widgets_values": [
|
||||
"ComfyUI"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"type": "Animation Builder (mtb)",
|
||||
"pos": [
|
||||
-1032,
|
||||
1274
|
||||
],
|
||||
"size": [
|
||||
210,
|
||||
306
|
||||
],
|
||||
"flags": {},
|
||||
"order": 2,
|
||||
"mode": 0,
|
||||
"outputs": [
|
||||
{
|
||||
"name": "frame",
|
||||
"type": "INT",
|
||||
"links": null,
|
||||
"shape": 3
|
||||
},
|
||||
{
|
||||
"name": "0-1 (scaled)",
|
||||
"type": "FLOAT",
|
||||
"links": [
|
||||
27,
|
||||
29
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 1
|
||||
},
|
||||
{
|
||||
"name": "count",
|
||||
"type": "INT",
|
||||
"links": null,
|
||||
"shape": 3
|
||||
},
|
||||
{
|
||||
"name": "loop_ended",
|
||||
"type": "BOOL",
|
||||
"links": [
|
||||
16
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 3
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "Animation Builder (mtb)"
|
||||
},
|
||||
"widgets_values": [
|
||||
30,
|
||||
1,
|
||||
1,
|
||||
90,
|
||||
1,
|
||||
"raw: 90\nframe: 0",
|
||||
"Done 😎!",
|
||||
"reset",
|
||||
"queue"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"type": "Get Batch From History (mtb)",
|
||||
"pos": [
|
||||
-369,
|
||||
1511
|
||||
],
|
||||
"size": [
|
||||
235.1999969482422,
|
||||
118
|
||||
],
|
||||
"flags": {},
|
||||
"order": 8,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "passthrough_image",
|
||||
"type": "IMAGE",
|
||||
"link": null
|
||||
},
|
||||
{
|
||||
"name": "enable",
|
||||
"type": "BOOL",
|
||||
"link": 16,
|
||||
"widget": {
|
||||
"name": "enable",
|
||||
"config": [
|
||||
"BOOL",
|
||||
{
|
||||
"default": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"slot_index": 1
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "i",
|
||||
"type": "IMAGE",
|
||||
"links": [
|
||||
17,
|
||||
18
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 0
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "Get Batch From History (mtb)"
|
||||
},
|
||||
"widgets_values": [
|
||||
false,
|
||||
30,
|
||||
0
|
||||
]
|
||||
}
|
||||
],
|
||||
"links": [
|
||||
[
|
||||
4,
|
||||
9,
|
||||
0,
|
||||
8,
|
||||
0,
|
||||
"MODEL"
|
||||
],
|
||||
[
|
||||
5,
|
||||
9,
|
||||
1,
|
||||
8,
|
||||
1,
|
||||
"CLIP"
|
||||
],
|
||||
[
|
||||
6,
|
||||
9,
|
||||
2,
|
||||
8,
|
||||
2,
|
||||
"VAE"
|
||||
],
|
||||
[
|
||||
8,
|
||||
13,
|
||||
0,
|
||||
12,
|
||||
0,
|
||||
"INT"
|
||||
],
|
||||
[
|
||||
9,
|
||||
12,
|
||||
0,
|
||||
11,
|
||||
1,
|
||||
"BOOL"
|
||||
],
|
||||
[
|
||||
10,
|
||||
10,
|
||||
0,
|
||||
11,
|
||||
0,
|
||||
"IMAGE"
|
||||
],
|
||||
[
|
||||
15,
|
||||
16,
|
||||
1,
|
||||
8,
|
||||
4,
|
||||
"STRING"
|
||||
],
|
||||
[
|
||||
16,
|
||||
17,
|
||||
3,
|
||||
18,
|
||||
1,
|
||||
"BOOL"
|
||||
],
|
||||
[
|
||||
17,
|
||||
18,
|
||||
0,
|
||||
20,
|
||||
0,
|
||||
"IMAGE"
|
||||
],
|
||||
[
|
||||
18,
|
||||
18,
|
||||
0,
|
||||
19,
|
||||
0,
|
||||
"IMAGE"
|
||||
],
|
||||
[
|
||||
24,
|
||||
14,
|
||||
0,
|
||||
8,
|
||||
3,
|
||||
"IMAGE"
|
||||
],
|
||||
[
|
||||
25,
|
||||
8,
|
||||
0,
|
||||
15,
|
||||
0,
|
||||
"IMAGE"
|
||||
],
|
||||
[
|
||||
26,
|
||||
11,
|
||||
0,
|
||||
14,
|
||||
0,
|
||||
"IMAGE"
|
||||
],
|
||||
[
|
||||
27,
|
||||
17,
|
||||
1,
|
||||
22,
|
||||
0,
|
||||
"FLOAT"
|
||||
],
|
||||
[
|
||||
28,
|
||||
22,
|
||||
0,
|
||||
8,
|
||||
5,
|
||||
"FLOAT"
|
||||
],
|
||||
[
|
||||
29,
|
||||
17,
|
||||
1,
|
||||
23,
|
||||
0,
|
||||
"FLOAT"
|
||||
],
|
||||
[
|
||||
30,
|
||||
23,
|
||||
0,
|
||||
14,
|
||||
1,
|
||||
"FLOAT"
|
||||
]
|
||||
],
|
||||
"groups": [
|
||||
{
|
||||
"title": "Init Image",
|
||||
"bounding": [
|
||||
-1730,
|
||||
215,
|
||||
716,
|
||||
713
|
||||
],
|
||||
"color": "#3f789e",
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"title": "Video Output",
|
||||
"bounding": [
|
||||
-426,
|
||||
1176,
|
||||
1223,
|
||||
787
|
||||
],
|
||||
"color": "#3f789e",
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"title": "Animation",
|
||||
"bounding": [
|
||||
-473,
|
||||
363,
|
||||
900,
|
||||
718
|
||||
],
|
||||
"color": "#3f789e",
|
||||
"locked": false
|
||||
}
|
||||
],
|
||||
"config": {},
|
||||
"extra": {},
|
||||
"version": 0.4
|
||||
}
|
||||
@@ -28,6 +28,10 @@ class LoadFaceEnhanceModel:
|
||||
@classmethod
|
||||
def get_models(cls):
|
||||
models_path = cls.get_models_root()
|
||||
|
||||
if not models_path.exists():
|
||||
log.warning(f"No models found at {models_path}")
|
||||
return []
|
||||
|
||||
return [
|
||||
x
|
||||
|
||||
+46
-14
@@ -22,6 +22,37 @@ import comfy.model_management as model_management
|
||||
|
||||
log = mklog(__name__)
|
||||
|
||||
class LoadFaceAnalysisModel:
|
||||
"""Loads a face analysis model"""
|
||||
|
||||
models = []
|
||||
@staticmethod
|
||||
def get_models() -> List[str]:
|
||||
models_path = os.path.join(folder_paths.models_dir, "insightface/*")
|
||||
models = glob.glob(models_path)
|
||||
models = [Path(x).name for x in models if x.endswith(".onnx") or x.endswith(".pth")]
|
||||
return models
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"faceswap_model": (
|
||||
["antelopev2", "buffalo_l", "buffalo_m", "buffalo_sc"],
|
||||
{"default": "buffalo_l"},
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("FACE_ANALYSIS_MODEL",)
|
||||
FUNCTION = "load_model"
|
||||
CATEGORY = "mtb/facetools"
|
||||
|
||||
def load_model(self, faceswap_model: str):
|
||||
face_analyser = insightface.app.FaceAnalysis(
|
||||
name=faceswap_model, root=os.path.join(folder_paths.models_dir, "insightface")
|
||||
)
|
||||
return (face_analyser,)
|
||||
|
||||
class LoadFaceSwapModel:
|
||||
"""Loads a faceswap model"""
|
||||
@@ -81,6 +112,7 @@ class FaceSwap:
|
||||
"image": ("IMAGE",),
|
||||
"reference": ("IMAGE",),
|
||||
"faces_index": ("STRING", {"default": "0"}),
|
||||
"faceanalysis_model": ("FACE_ANALYSIS_MODEL", {"default": "None"}),
|
||||
"faceswap_model": ("FACESWAP_MODEL", {"default": "None"}),
|
||||
"debug": ("BOOL", {"default": False}),
|
||||
},
|
||||
@@ -96,6 +128,7 @@ class FaceSwap:
|
||||
image: torch.Tensor,
|
||||
reference: torch.Tensor,
|
||||
faces_index: str,
|
||||
faceanalysis_model,
|
||||
faceswap_model,
|
||||
debug=False,
|
||||
):
|
||||
@@ -107,7 +140,7 @@ class FaceSwap:
|
||||
int(x) for x in faces_index.strip(",").split(",") if x.isnumeric()
|
||||
}
|
||||
sys.stdout = NullWriter()
|
||||
swapped = swap_face(ref, img, faceswap_model, face_ids)
|
||||
swapped = swap_face(faceanalysis_model,ref, img, faceswap_model, face_ids)
|
||||
sys.stdout = sys.__stdout__
|
||||
return pil2tensor(swapped)
|
||||
|
||||
@@ -121,8 +154,8 @@ class FaceSwap:
|
||||
image = do_swap(image)
|
||||
|
||||
else:
|
||||
image = [do_swap(image[i]) for i in range(batch_count)]
|
||||
image = torch.cat(image, dim=0)
|
||||
image_batch = [do_swap(image[i]) for i in range(batch_count)]
|
||||
image = torch.cat(image_batch, dim=0)
|
||||
|
||||
return (image,)
|
||||
|
||||
@@ -131,17 +164,15 @@ class FaceSwap:
|
||||
|
||||
|
||||
# region face swap utils
|
||||
def get_face_single(img_data: np.ndarray, face_index=0, det_size=(640, 640)):
|
||||
face_analyser = insightface.app.FaceAnalysis(
|
||||
name="buffalo_l", root=os.path.join(folder_paths.models_dir, "insightface")
|
||||
)
|
||||
def get_face_single(face_analyser,img_data: np.ndarray, face_index=0, det_size=(640, 640)):
|
||||
|
||||
face_analyser.prepare(ctx_id=0, det_size=det_size)
|
||||
face = face_analyser.get(img_data)
|
||||
|
||||
if len(face) == 0 and det_size[0] > 320 and det_size[1] > 320:
|
||||
log.debug("No face ed, trying again with smaller image")
|
||||
det_size_half = (det_size[0] // 2, det_size[1] // 2)
|
||||
return get_face_single(img_data, face_index=face_index, det_size=det_size_half)
|
||||
return get_face_single(face_analyser,img_data, face_index=face_index, det_size=det_size_half)
|
||||
|
||||
try:
|
||||
return sorted(face, key=lambda x: x.bbox[0])[face_index]
|
||||
@@ -150,6 +181,7 @@ def get_face_single(img_data: np.ndarray, face_index=0, det_size=(640, 640)):
|
||||
|
||||
|
||||
def swap_face(
|
||||
face_analyser,
|
||||
source_img: Union[Image.Image, List[Image.Image]],
|
||||
target_img: Union[Image.Image, List[Image.Image]],
|
||||
face_swapper_model,
|
||||
@@ -161,14 +193,14 @@ def swap_face(
|
||||
result_image = target_img
|
||||
|
||||
if face_swapper_model is not None:
|
||||
source_img = cv2.cvtColor(np.array(source_img), cv2.COLOR_RGB2BGR)
|
||||
target_img = cv2.cvtColor(np.array(target_img), cv2.COLOR_RGB2BGR)
|
||||
source_face = get_face_single(source_img, face_index=0)
|
||||
cv_source_img = cv2.cvtColor(np.array(source_img), cv2.COLOR_RGB2BGR)
|
||||
cv_target_img = cv2.cvtColor(np.array(target_img), cv2.COLOR_RGB2BGR)
|
||||
source_face = get_face_single(face_analyser,cv_source_img, face_index=0)
|
||||
if source_face is not None:
|
||||
result = target_img
|
||||
result = cv_target_img
|
||||
|
||||
for face_num in faces_index:
|
||||
target_face = get_face_single(target_img, face_index=face_num)
|
||||
target_face = get_face_single(face_analyser,cv_target_img, face_index=face_num)
|
||||
if target_face is not None:
|
||||
sys.stdout = NullWriter()
|
||||
result = face_swapper_model.get(result, target_face, source_face)
|
||||
@@ -187,4 +219,4 @@ def swap_face(
|
||||
# endregion face swap utils
|
||||
|
||||
|
||||
__nodes__ = [FaceSwap, LoadFaceSwapModel]
|
||||
__nodes__ = [FaceSwap, LoadFaceSwapModel, LoadFaceAnalysisModel]
|
||||
|
||||
+1
-1
@@ -13,6 +13,6 @@
|
||||
"reportMissingImports": true,
|
||||
"reportMissingTypeStubs": false,
|
||||
"pythonVersion": "3.10",
|
||||
"pythonPlatform": "Windows",
|
||||
"pythonPlatform": "All",
|
||||
"reportOptionalMemberAccess": "none"
|
||||
}
|
||||
+1
-1
@@ -8,7 +8,7 @@ tensorflow<2.11.0; platform_system == "Windows"
|
||||
tb-nightly==2.12.0a20230126; platform_system == "Windows"
|
||||
tensorflow; platform_system != "Windows"
|
||||
# the old tf version on windows comes with a breaking protobuf version
|
||||
protobuf==3.19.6
|
||||
protobuf==3.20.2; platform_system == "Windows"
|
||||
gdown @ git+https://github.com/melMass/gdown@main
|
||||
mmdet==3.0.0
|
||||
facexlib==0.3.0
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
## Core
|
||||
These 3 script should cannot be used independently and must all be present to work
|
||||
- `comfy_shared`: library of methods used in `mtb_widgets` and `debug`
|
||||
|
||||
## Standalone
|
||||
These scripts can be taken and placed independently of `comfy_mtb` or any other files, mimicking what pythongosss did for their [Custom Scripts](https://github.com/pythongosssss/ComfyUI-Custom-Scripts/tree/main/js)
|
||||
|
||||
- **imageFeed**: a fork of pythongosssss's image feed, it adds support for: a lightbox to see images bigger, a way to load the current session history (in case of a web page reload), and different icons, most of the work come from the original script.
|
||||
- 
|
||||
|
||||
- **notify**: a basic toast notification system that I use in some places accross mtb, it can be used by simply calling `window.MTB.notify("Hello world!")`
|
||||

|
||||
+16
-2
@@ -34,7 +34,7 @@ const styles = {
|
||||
zIndex: 9999999,
|
||||
fontSize: '30px',
|
||||
cursor: 'pointer',
|
||||
pointerEvents: 'bounding-box',
|
||||
pointerEvents: 'auto',
|
||||
...extra,
|
||||
}),
|
||||
img_list: {
|
||||
@@ -53,10 +53,21 @@ let currentImageIndex = 0
|
||||
const imageUrls = []
|
||||
|
||||
let image_menu = null
|
||||
let activated = true
|
||||
|
||||
app.registerExtension({
|
||||
name: 'mtb.ImageFeed',
|
||||
setup: async () => {
|
||||
init: async () => {
|
||||
const pythongossFeed = app.extensions.find(
|
||||
(e) => e.name == 'pysssss.ImageFeed'
|
||||
)
|
||||
if (pythongossFeed) {
|
||||
console.warn(
|
||||
"[mtb] - Aborting the loading of mtb's imageFeed in favor of pysssss.ImageFeed"
|
||||
)
|
||||
activated = false // just in case other methods are added later on
|
||||
return
|
||||
}
|
||||
// - HTML & CSS
|
||||
//- lightbox
|
||||
const lightboxContainer = document.createElement('div')
|
||||
@@ -209,6 +220,9 @@ app.registerExtension({
|
||||
Object.assign(but.style, {
|
||||
height: '120px',
|
||||
width: '120px',
|
||||
border: 'none',
|
||||
padding: 0,
|
||||
margin: 0,
|
||||
})
|
||||
Object.assign(img.style, {
|
||||
width: '100%',
|
||||
|
||||
+47
-10
@@ -688,7 +688,34 @@ const mtb_widgets = {
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'Save Gif (mtb)': {
|
||||
//TODO: remove this non sense
|
||||
case 'Get Batch From History (mtb)': {
|
||||
const onNodeCreated = nodeType.prototype.onNodeCreated
|
||||
nodeType.prototype.onNodeCreated = function () {
|
||||
const r = onNodeCreated
|
||||
? onNodeCreated.apply(this, arguments)
|
||||
: undefined
|
||||
const internal_count = this.widgets.find(
|
||||
(w) => w.name === 'internal_count'
|
||||
)
|
||||
shared.hideWidgetForGood(this, internal_count)
|
||||
internal_count.afterQueued = function () {
|
||||
this.value++
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
const onExecuted = nodeType.prototype.onExecuted
|
||||
nodeType.prototype.onExecuted = function (message) {
|
||||
const r = onExecuted ? onExecuted.apply(this, message) : undefined
|
||||
return r
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
case 'Save Gif (mtb)':
|
||||
case 'Save Animated Image (mtb)': {
|
||||
const onExecuted = nodeType.prototype.onExecuted
|
||||
nodeType.prototype.onExecuted = function (message) {
|
||||
const prefix = 'anything_'
|
||||
@@ -704,15 +731,25 @@ const mtb_widgets = {
|
||||
}
|
||||
|
||||
let imgURLs = []
|
||||
if (message && message.gif) {
|
||||
imgURLs = imgURLs.concat(
|
||||
message.gif.map((params) => {
|
||||
return api.apiURL(
|
||||
'/view?' + new URLSearchParams(params).toString()
|
||||
)
|
||||
})
|
||||
)
|
||||
|
||||
if (message) {
|
||||
if (message.gif) {
|
||||
imgURLs = imgURLs.concat(
|
||||
message.gif.map((params) => {
|
||||
return api.apiURL(
|
||||
'/view?' + new URLSearchParams(params).toString()
|
||||
)
|
||||
})
|
||||
)
|
||||
}
|
||||
if (message.apng) {
|
||||
imgURLs = imgURLs.concat(
|
||||
message.apng.map((params) => {
|
||||
return api.apiURL(
|
||||
'/view?' + new URLSearchParams(params).toString()
|
||||
)
|
||||
})
|
||||
)
|
||||
}
|
||||
let i = 0
|
||||
for (const img of imgURLs) {
|
||||
const w = this.addCustomWidget(
|
||||
|
||||
Reference in New Issue
Block a user