add:easy controlnetLoaderADV node
This commit is contained in:
@@ -14,6 +14,9 @@
|
||||
"easy controlnetLoader": {
|
||||
"title": "简易Controlnet"
|
||||
},
|
||||
"easy controlnetLoaderADV": {
|
||||
"title": "简易Controlnet(高级)"
|
||||
},
|
||||
"easy LLLite": {
|
||||
"title": "简易LLLite"
|
||||
},
|
||||
|
||||
+14
-3
@@ -19,15 +19,26 @@ EasyUse is simplified on the basis of [tinyterraNodes](https://github.com/TinyTe
|
||||
|
||||
### Updated
|
||||
|
||||
**[Updated at 12/13/2023]**
|
||||
**2023-12-14**
|
||||
|
||||
- `easy a1111Loader` and `easy comfyLoader` added `batch_size` of required input parameters
|
||||
- Added the `easy controlnetLoaderADV` node
|
||||
- `easy controlnetLoaderADV` and `easy controlnetLoader` added `control_net ` of optional input parameters
|
||||
- `easy preSampling` and `easy preSamplingAdvanced` added 'image_to_latent' optional input parameters
|
||||
- Added the `easy imageSizeBySide` node, which can be output as a long side or a short side
|
||||
|
||||
<details>
|
||||
<summary><b>Updated at 12/13/2023</b></summary>
|
||||
|
||||
- Added the `easy LLLiteLoader` node, if you have pre-installed the kohya-ss/ControlNet-LLLite-ComfyUI package, please move the model files in the models to `ComfyUI\models\controlnet\` (i.e. in the default controlnet path of comfy, please do not change the file name of the model, otherwise it will not be read).
|
||||
- Modify `easy controlnetLoader` to the bottom of the loader category.
|
||||
- Added size display for `easy imageSize` and `easy imageSizeByLongerSize` outputs.
|
||||
</details>
|
||||
|
||||
**[Updated at 12/11/2023]**
|
||||
|
||||
<details>
|
||||
<summary><b>Updated at 12/11/2023</b></summary>
|
||||
- Added the `showSpentTime` node to display the time spent on image diffusion and the time spent on VAE decoding images
|
||||
</details>
|
||||
|
||||
### Major optimizations
|
||||
|
||||
|
||||
@@ -15,19 +15,31 @@
|
||||
|
||||
<img src="./docs/workflow_node_compare.png">
|
||||
|
||||
EasyUse 在 [tinyterraNodes](https://github.com/TinyTerra/ComfyUI_tinyterraNodes) 的基础上做了简化,在简化的节点中去除了过多的传入和传出参数,建议您配合 [tinyterraNodes](https://github.com/TinyTerra/ComfyUI_tinyterraNodes) 中的 **pipeIn**、**pipeOut**、**pipeEdit** 使用,可参考下方示例里 [图生图的工作流](https://github.com/yolain/ComfyUI-Easy-Use?tab=readme-ov-file#%E5%9B%BE%E7%94%9F%E5%9B%BEcontrolnet)。
|
||||
EasyUse 在 [tinyterraNodes](https://github.com/TinyTerra/ComfyUI_tinyterraNodes) 的基础上做了简化,在简化的节点中去除了过多的传入和传出参数,建议您配合 [tinyterraNodes](https://github.com/TinyTerra/ComfyUI_tinyterraNodes) 中的 **pipeIn**、**pipeOut**、**pipeEdit** 使用,可参考下方示例里 [工作流](https://github.com/yolain/ComfyUI-Easy-Use?tab=readme-ov-file#sdturbo%E9%AB%98%E6%B8%85%E4%BF%AE%E5%A4%8Dsvd)。
|
||||
|
||||
### 更新
|
||||
|
||||
**2023-12-13**
|
||||
**2023-12-14**
|
||||
|
||||
- `easy a1111Loader` 和 `easy comfyLoader` 新增 `batch_size` 传入参数
|
||||
- 新增 `easy controlnetLoaderADV` 节点
|
||||
- `easy controlnetLoaderADV` 和 `easy controlnetLoader` 新增 `control_net` 可选传入参数
|
||||
- `easy preSampling` 和 `easy preSamplingAdvanced` 新增 `image_to_latent` 可选传入参数
|
||||
- 新增 `easy imageSizeBySide` 节点,可选输出为长边或短边
|
||||
|
||||
<details>
|
||||
<summary><b>2023-12-13</b></summary>
|
||||
|
||||
- 新增 `easy LLLiteLoader` 节点,如果您预先安装过 kohya-ss/ControlNet-LLLite-ComfyUI 包,请将 models 里的模型文件移动至 ComfyUI\models\controlnet\ (即comfy默认的controlnet路径里,请勿修改模型的文件名,不然会读取不到)。
|
||||
- 修改 `easy controlnetLoader` 到 loader 分类底下。
|
||||
- 新增 `easy imageSize` 和 `easy imageSizeByLongerSize` 输出的尺寸显示。
|
||||
</details>
|
||||
|
||||
**2023-12-11**
|
||||
<details>
|
||||
<summary><b>2023-12-11</b></summary>
|
||||
|
||||
- 新增 `easy showSpentTime` 节点用于展示图片推理花费时间与VAE解码花费时间。
|
||||
</details>
|
||||
|
||||
### 主要的优化
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 538 KiB After Width: | Height: | Size: 513 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 323 KiB After Width: | Height: | Size: 324 KiB |
+152
-34
@@ -28,7 +28,7 @@ from comfy_extras.chainner_models import model_loading
|
||||
from typing import Dict, List, Optional, Tuple, Union, Any
|
||||
from .adv_encode import advanced_encode, advanced_encode_XL
|
||||
|
||||
from nodes import MAX_RESOLUTION, VAEEncode, VAEEncodeTiled, VAEDecode, VAEDecodeTiled
|
||||
from nodes import MAX_RESOLUTION, RepeatLatentBatch
|
||||
from .config import BASE_RESOLUTIONS
|
||||
|
||||
from server import PromptServer
|
||||
@@ -781,6 +781,7 @@ class a1111Loader:
|
||||
|
||||
"positive": ("STRING", {"default": "Positive", "multiline": True}),
|
||||
"negative": ("STRING", {"default": "Negative", "multiline": True}),
|
||||
"batch_size": ("INT", {"default": 1, "min": 1, "max": 64}),
|
||||
},
|
||||
"optional": {"optional_lora_stack": ("LORA_STACK",)},
|
||||
"hidden": {"prompt": "PROMPT", "positive_weight_interpretation": "A1111", "negative_weight_interpretation": "A1111"}, "my_unique_id": "UNIQUE_ID"}
|
||||
@@ -794,7 +795,7 @@ class a1111Loader:
|
||||
def adv_pipeloader(self, ckpt_name, vae_name, clip_skip,
|
||||
lora_name, lora_model_strength, lora_clip_strength,
|
||||
resolution, empty_latent_width, empty_latent_height,
|
||||
positive, negative, optional_lora_stack=None, prompt=None,
|
||||
positive, negative, batch_size, optional_lora_stack=None, prompt=None,
|
||||
positive_weight_interpretation='A1111', negative_weight_interpretation='A1111',
|
||||
my_unique_id=None
|
||||
):
|
||||
@@ -813,7 +814,7 @@ class a1111Loader:
|
||||
raise ValueError("Invalid base_resolution format.")
|
||||
|
||||
# Create Empty Latent
|
||||
latent = torch.zeros([1, 4, empty_latent_height // 8, empty_latent_width // 8]).cpu()
|
||||
latent = torch.zeros([batch_size, 4, empty_latent_height // 8, empty_latent_width // 8]).cpu()
|
||||
samples = {"samples": latent}
|
||||
|
||||
# Clean models from loaded_objects
|
||||
@@ -894,7 +895,7 @@ class a1111Loader:
|
||||
"negative_balance": None,
|
||||
"empty_latent_width": empty_latent_width,
|
||||
"empty_latent_height": empty_latent_height,
|
||||
"batch_size": 1,
|
||||
"batch_size": batch_size,
|
||||
"seed": 0,
|
||||
"empty_samples": samples, }
|
||||
}
|
||||
@@ -921,6 +922,8 @@ class comfyLoader:
|
||||
|
||||
"positive": ("STRING", {"default": "Positive", "multiline": True}),
|
||||
"negative": ("STRING", {"default": "Negative", "multiline": True}),
|
||||
|
||||
"batch_size": ("INT", {"default": 1, "min": 1, "max": 64}),
|
||||
},
|
||||
"optional": {"optional_lora_stack": ("LORA_STACK",)},
|
||||
"hidden": {"prompt": "PROMPT", "positive_weight_interpretation": "comfy", "negative_weight_interpretation": "comfy"}, "my_unique_id": "UNIQUE_ID"}
|
||||
@@ -934,7 +937,7 @@ class comfyLoader:
|
||||
def adv_pipeloader(self, ckpt_name, vae_name, clip_skip,
|
||||
lora_name, lora_model_strength, lora_clip_strength,
|
||||
resolution, empty_latent_width, empty_latent_height,
|
||||
positive, negative, optional_lora_stack=None, prompt=None,
|
||||
positive, negative, batch_size, optional_lora_stack=None, prompt=None,
|
||||
positive_weight_interpretation='comfy', negative_weight_interpretation='comfy',
|
||||
my_unique_id=None
|
||||
):
|
||||
@@ -943,7 +946,7 @@ class comfyLoader:
|
||||
ckpt_name, vae_name, clip_skip,
|
||||
lora_name, lora_model_strength, lora_clip_strength,
|
||||
resolution, empty_latent_width, empty_latent_height,
|
||||
positive, negative, optional_lora_stack, prompt,
|
||||
positive, negative, batch_size, optional_lora_stack, prompt,
|
||||
positive_weight_interpretation, negative_weight_interpretation,
|
||||
my_unique_id
|
||||
)
|
||||
@@ -958,12 +961,11 @@ class controlnetSimple:
|
||||
return {
|
||||
"required": {
|
||||
"pipe": ("PIPE_LINE",),
|
||||
"control_net_name": (folder_paths.get_filename_list("controlnet"),),
|
||||
"image": ("IMAGE",),
|
||||
"control_net_name": (folder_paths.get_filename_list("controlnet"),),
|
||||
},
|
||||
"optional": {
|
||||
"positive": ("CONDITIONING",),
|
||||
"negative": ("CONDITIONING",),
|
||||
"control_net": ("CONTROL_NET",),
|
||||
"strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01})
|
||||
}
|
||||
}
|
||||
@@ -975,16 +977,17 @@ class controlnetSimple:
|
||||
FUNCTION = "controlnetApply"
|
||||
CATEGORY = "EasyUse/Loader"
|
||||
|
||||
def controlnetApply(self, pipe, control_net_name, image, positive=None, negative=None, strength=1):
|
||||
controlnet_path = folder_paths.get_full_path("controlnet", control_net_name)
|
||||
control_net = comfy.controlnet.load_controlnet(controlnet_path)
|
||||
def controlnetApply(self, pipe, image, control_net_name, control_net=None,strength=1):
|
||||
if control_net is None:
|
||||
controlnet_path = folder_paths.get_full_path("controlnet", control_net_name)
|
||||
control_net = comfy.controlnet.load_controlnet(controlnet_path)
|
||||
control_hint = image.movedim(-1, 1)
|
||||
|
||||
_positive = pipe["positive"] if positive is None else positive
|
||||
_negative = pipe["negative"] if negative is None else negative
|
||||
positive = pipe["positive"]
|
||||
negative = pipe["negative"]
|
||||
|
||||
if strength != 0:
|
||||
if _negative is None:
|
||||
if negative is None:
|
||||
p = []
|
||||
for t in positive:
|
||||
n = [t[0], t[1].copy()]
|
||||
@@ -994,11 +997,11 @@ class controlnetSimple:
|
||||
n[1]['control'] = c_net
|
||||
n[1]['control_apply_to_uncond'] = True
|
||||
p.append(n)
|
||||
_positive = p
|
||||
positive = p
|
||||
else:
|
||||
cnets = {}
|
||||
out = []
|
||||
for conditioning in [_positive, _negative]:
|
||||
for conditioning in [positive, negative]:
|
||||
c = []
|
||||
for t in conditioning:
|
||||
d = t[1].copy()
|
||||
@@ -1016,12 +1019,94 @@ class controlnetSimple:
|
||||
n = [t[0], d]
|
||||
c.append(n)
|
||||
out.append(c)
|
||||
_positive = out[0]
|
||||
_negative = out[1]
|
||||
positive = out[0]
|
||||
negative = out[1]
|
||||
|
||||
# 拼接条件
|
||||
positive = _positive if positive is None else _positive + pipe['positive']
|
||||
negative = _negative if negative is None else _negative + pipe['negative']
|
||||
new_pipe = {
|
||||
"model": pipe['model'],
|
||||
"positive": positive,
|
||||
"negative": negative,
|
||||
"vae": pipe['vae'],
|
||||
"clip": pipe['clip'],
|
||||
|
||||
"samples": pipe["samples"],
|
||||
"images": pipe["images"],
|
||||
"seed": 0,
|
||||
|
||||
"loader_settings": pipe["loader_settings"]
|
||||
}
|
||||
|
||||
return (new_pipe,)
|
||||
|
||||
# controlnetADV
|
||||
class controlnetAdvanced:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {
|
||||
"required": {
|
||||
"pipe": ("PIPE_LINE",),
|
||||
"image": ("IMAGE",),
|
||||
"control_net_name": (folder_paths.get_filename_list("controlnet"),),
|
||||
},
|
||||
"optional": {
|
||||
"control_net": ("CONTROL_NET",),
|
||||
"strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
|
||||
"start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
||||
"end_percent": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001})
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("PIPE_LINE",)
|
||||
RETURN_NAMES = ("pipe",)
|
||||
OUTPUT_NODE = True
|
||||
|
||||
FUNCTION = "controlnetApply"
|
||||
CATEGORY = "EasyUse/Loader"
|
||||
|
||||
def controlnetApply(self, pipe, image, control_net_name, control_net=None, strength=1, start_percent=0, end_percent=1):
|
||||
if control_net is None:
|
||||
controlnet_path = folder_paths.get_full_path("controlnet", control_net_name)
|
||||
control_net = comfy.controlnet.load_controlnet(controlnet_path)
|
||||
control_hint = image.movedim(-1, 1)
|
||||
|
||||
positive = pipe["positive"]
|
||||
negative = pipe["negative"]
|
||||
|
||||
if strength != 0:
|
||||
if negative is None:
|
||||
p = []
|
||||
for t in positive:
|
||||
n = [t[0], t[1].copy()]
|
||||
c_net = control_net.copy().set_cond_hint(control_hint, strength)
|
||||
if 'control' in t[1]:
|
||||
c_net.set_previous_controlnet(t[1]['control'])
|
||||
n[1]['control'] = c_net
|
||||
n[1]['control_apply_to_uncond'] = True
|
||||
p.append(n)
|
||||
positive = p
|
||||
else:
|
||||
cnets = {}
|
||||
out = []
|
||||
for conditioning in [positive, negative]:
|
||||
c = []
|
||||
for t in conditioning:
|
||||
d = t[1].copy()
|
||||
|
||||
prev_cnet = d.get('control', None)
|
||||
if prev_cnet in cnets:
|
||||
c_net = cnets[prev_cnet]
|
||||
else:
|
||||
c_net = control_net.copy().set_cond_hint(control_hint, strength, (start_percent, end_percent))
|
||||
c_net.set_previous_controlnet(prev_cnet)
|
||||
cnets[prev_cnet] = c_net
|
||||
|
||||
d['control'] = c_net
|
||||
d['control_apply_to_uncond'] = False
|
||||
n = [t[0], d]
|
||||
c.append(n)
|
||||
out.append(c)
|
||||
positive = out[0]
|
||||
negative = out[1]
|
||||
|
||||
new_pipe = {
|
||||
"model": pipe['model'],
|
||||
@@ -1095,6 +1180,9 @@ class samplerSettings:
|
||||
"seed_num": ("INT", {"default": 0, "min": 0, "max": 1125899906842624}),
|
||||
"control_before_generate": (["fixed", "increment", "decrement", "randomize"], {"default": "randomize"}),
|
||||
},
|
||||
"optional": {
|
||||
"image_to_latent": ("IMAGE",),
|
||||
},
|
||||
"hidden":
|
||||
{"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO", "my_unique_id": "UNIQUE_ID"},
|
||||
}
|
||||
@@ -1106,7 +1194,7 @@ class samplerSettings:
|
||||
FUNCTION = "settings"
|
||||
CATEGORY = "EasyUse/PreSampling"
|
||||
|
||||
def settings(self, pipe, steps, cfg, sampler_name, scheduler, denoise, seed_num, control_before_generate, prompt=None, extra_pnginfo=None, my_unique_id=None):
|
||||
def settings(self, pipe, steps, cfg, sampler_name, scheduler, denoise, seed_num, control_before_generate, image_to_latent=None, prompt=None, extra_pnginfo=None, my_unique_id=None):
|
||||
|
||||
# seed生成
|
||||
seed_num = control_seed(control_before_generate, seed_num)
|
||||
@@ -1117,6 +1205,17 @@ class samplerSettings:
|
||||
length = len(node["widgets_values"])
|
||||
node["widgets_values"][length-2] = seed_num
|
||||
|
||||
vae = pipe["vae"]
|
||||
# 图生图转换
|
||||
if image_to_latent is not None:
|
||||
batch_size = pipe["loader_settings"]["batch_size"] if "batch_size" in pipe["loader_settings"] else 1
|
||||
samples = {"samples": vae.encode(image_to_latent)}
|
||||
samples = RepeatLatentBatch().repeat(samples, batch_size)[0]
|
||||
images = image_to_latent
|
||||
else:
|
||||
samples = pipe["samples"]
|
||||
images = pipe["images"]
|
||||
print(samples)
|
||||
new_pipe = {
|
||||
"model": pipe['model'],
|
||||
"positive": pipe['positive'],
|
||||
@@ -1124,8 +1223,8 @@ class samplerSettings:
|
||||
"vae": pipe['vae'],
|
||||
"clip": pipe['clip'],
|
||||
|
||||
"samples": pipe["samples"],
|
||||
"images": pipe["images"],
|
||||
"samples": samples,
|
||||
"images": images,
|
||||
"seed": seed_num,
|
||||
|
||||
"loader_settings": {
|
||||
@@ -1163,6 +1262,9 @@ class samplerSettingsAdvanced:
|
||||
"seed_num": ("INT", {"default": 0, "min": 0, "max": 1125899906842624}),
|
||||
"control_before_generate": (["fixed", "increment", "decrement", "randomize"], {"default": "randomize"}),
|
||||
},
|
||||
"optional": {
|
||||
"image_to_latent": ("Image",)
|
||||
},
|
||||
"hidden":
|
||||
{"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO", "my_unique_id": "UNIQUE_ID"},
|
||||
}
|
||||
@@ -1174,7 +1276,7 @@ class samplerSettingsAdvanced:
|
||||
FUNCTION = "settings"
|
||||
CATEGORY = "EasyUse/PreSampling"
|
||||
|
||||
def settings(self, pipe, steps, cfg, sampler_name, scheduler, start_at_step, end_at_step, add_noise, seed_num, control_before_generate, prompt=None, extra_pnginfo=None, my_unique_id=None):
|
||||
def settings(self, pipe, steps, cfg, sampler_name, scheduler, start_at_step, end_at_step, add_noise, seed_num, control_before_generate, image_to_latent=None, prompt=None, extra_pnginfo=None, my_unique_id=None):
|
||||
|
||||
# seed生成
|
||||
seed_num = control_seed(control_before_generate, seed_num)
|
||||
@@ -1185,6 +1287,17 @@ class samplerSettingsAdvanced:
|
||||
length = len(node["widgets_values"])
|
||||
node["widgets_values"][length-2] = seed_num
|
||||
|
||||
# 图生图转换
|
||||
vae = pipe["vae"]
|
||||
if image_to_latent is not None:
|
||||
batch_size = pipe["loader_settings"]["batch_size"] if "batch_size" in pipe["loader_settings"] else 1
|
||||
samples = {"samples": vae.encode(image_to_latent)}
|
||||
samples = RepeatLatentBatch().repeat(samples, batch_size)[0]
|
||||
images = image_to_latent
|
||||
else:
|
||||
samples = pipe["samples"]
|
||||
images = pipe["images"]
|
||||
|
||||
new_pipe = {
|
||||
"model": pipe['model'],
|
||||
"positive": pipe['positive'],
|
||||
@@ -1192,8 +1305,8 @@ class samplerSettingsAdvanced:
|
||||
"vae": pipe['vae'],
|
||||
"clip": pipe['clip'],
|
||||
|
||||
"samples": pipe["samples"],
|
||||
"images": pipe["images"],
|
||||
"samples": samples,
|
||||
"images": images,
|
||||
"seed": seed_num,
|
||||
|
||||
"loader_settings": {
|
||||
@@ -1516,9 +1629,6 @@ class samplerSimple:
|
||||
if add_noise == "disable":
|
||||
disable_noise = True
|
||||
|
||||
def vae_decode_latent(vae, samples, tile_size):
|
||||
return VAEDecodeTiled().decode(vae, samples, tile_size)[0] if tile_size is not None else VAEDecode().decode(vae, samples)[0]
|
||||
|
||||
def process_sample_state(pipe, samp_model, samp_clip, samp_samples, samp_vae, samp_seed, samp_positive,
|
||||
samp_negative,
|
||||
steps, start_step, last_step, cfg, sampler_name, scheduler, denoise,
|
||||
@@ -1533,7 +1643,13 @@ class samplerSimple:
|
||||
# 推理结束时间
|
||||
end_time = int(time.time() * 1000)
|
||||
# 解码图片
|
||||
samp_images = vae_decode_latent(samp_vae, samp_samples, tile_size)
|
||||
latent = samp_samples["samples"]
|
||||
|
||||
# 解码图片
|
||||
if tile_size is not None:
|
||||
samp_images = samp_vae.decode_tiled(latent, tile_x=tile_size // 8, tile_y=tile_size // 8, )
|
||||
else:
|
||||
samp_images = samp_vae.decode(latent).cpu()
|
||||
|
||||
# 推理总耗时(包含解码)
|
||||
end_decode_time = int(time.time() * 1000)
|
||||
@@ -1686,8 +1802,8 @@ class samplerSDTurbo:
|
||||
latent = samp_samples['samples']
|
||||
|
||||
# 解码图片
|
||||
if tile_size:
|
||||
samp_images = (samp_vae.decode_tiled(latent, tile_x=tile_size // 8, tile_y=tile_size // 8, ),)
|
||||
if tile_size is not None:
|
||||
samp_images = samp_vae.decode_tiled(latent, tile_x=tile_size // 8, tile_y=tile_size // 8, )
|
||||
else:
|
||||
samp_images = samp_vae.decode(latent).cpu()
|
||||
|
||||
@@ -1770,6 +1886,7 @@ NODE_CLASS_MAPPINGS = {
|
||||
"easy a1111Loader": a1111Loader,
|
||||
"easy comfyLoader": comfyLoader,
|
||||
"easy controlnetLoader": controlnetSimple,
|
||||
"easy controlnetLoaderADV": controlnetAdvanced,
|
||||
"easy globalSeed": globalSeed,
|
||||
"easy preSampling": samplerSettings,
|
||||
"easy preSamplingAdvanced": samplerSettingsAdvanced,
|
||||
@@ -1785,6 +1902,7 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"easy a1111Loader": "EasyLoader (A1111)",
|
||||
"easy comfyLoader": "EasyLoader (comfy)",
|
||||
"easy controlnetLoader": "EasyControlnet",
|
||||
"easy controlnetLoaderADV": "EasyControlnet (Advanced)",
|
||||
"easy globalSeed": "GlobalSeed",
|
||||
"easy preSampling": "PreSampling",
|
||||
"easy preSamplingAdvanced": "PreSampling (Advanced)",
|
||||
|
||||
+34
-1
@@ -119,7 +119,38 @@ class imageSize:
|
||||
result = (0, 0)
|
||||
return {"ui": {"text": "Width: "+str(result[0])+" , Height: "+str(result[1])}, "result": result}
|
||||
|
||||
# 图像尺寸
|
||||
# 图像尺寸(最长边)
|
||||
class imageSizeBySide:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"image": ("IMAGE",),
|
||||
"side": (["Longest", "Shortest"],)
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("INT",)
|
||||
RETURN_NAMES = ("resolution",)
|
||||
FUNCTION = "image_side"
|
||||
|
||||
CATEGORY = "EasyUse/Image"
|
||||
|
||||
def image_side(self, image, side):
|
||||
image = tensor2pil(image)
|
||||
if image.size:
|
||||
if side == "Longest":
|
||||
result = (image.size[0],) if image.size[0] > image.size[1] else (image.size[1],)
|
||||
elif side == 'Shortest':
|
||||
result = (image.size[0],) if image.size[0] < image.size[1] else (image.size[1],)
|
||||
else:
|
||||
result = (0,)
|
||||
return {"ui": {"text": str(result[0])}, "result": result}
|
||||
|
||||
# 图像尺寸(最长边)
|
||||
class imageSizeByLongerSide:
|
||||
def __init__(self):
|
||||
pass
|
||||
@@ -152,11 +183,13 @@ class imageSizeByLongerSide:
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"easy imageInsetCrop": imageInsetCrop,
|
||||
"easy imageSize": imageSize,
|
||||
"easy imageSizeBySide": imageSizeBySide,
|
||||
"easy imageSizeByLongerSide": imageSizeByLongerSide
|
||||
}
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"easy imageInsetCrop": "ImageInsetCrop",
|
||||
"easy imageSize": "ImageSize",
|
||||
"easy imageSizeBySide": "ImageSize (Side)",
|
||||
"easy imageSizeByLongerSide": "ImageSize (LongerSide)"
|
||||
}
|
||||
+4
-4
@@ -4,8 +4,8 @@ import os
|
||||
import folder_paths
|
||||
import comfy
|
||||
|
||||
def get_file_list(path):
|
||||
return [file for file in os.listdir(path) if file != "put_models_here.txt" and "lllite" in file]
|
||||
def get_file_list(filenames):
|
||||
return [file for file in filenames if file != "put_models_here.txt" and "lllite" in file]
|
||||
|
||||
|
||||
def extra_options_to_module_prefix(extra_options):
|
||||
@@ -252,7 +252,7 @@ class LLLiteLoader:
|
||||
return {
|
||||
"required": {
|
||||
"model": ("MODEL",),
|
||||
"model_name": (get_file_list(folder_paths.get_folder_paths("controlnet")[0]),),
|
||||
"model_name": (get_file_list(folder_paths.get_filename_list("controlnet")),),
|
||||
"cond_image": ("IMAGE",),
|
||||
"strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
|
||||
"steps": ("INT", {"default": 0, "min": 0, "max": 200, "step": 1}),
|
||||
@@ -268,7 +268,7 @@ class LLLiteLoader:
|
||||
def load_lllite(self, model, model_name, cond_image, strength, steps, start_percent, end_percent):
|
||||
# cond_image is b,h,w,3, 0-1
|
||||
|
||||
model_path = os.path.join(folder_paths.get_folder_paths("controlnet")[0], model_name)
|
||||
model_path = os.path.join(folder_paths.get_full_path("controlnet", model_name))
|
||||
|
||||
model_lllite = model.clone()
|
||||
patch = load_control_net_lllite_patch(model_path, cond_image, strength, steps, start_percent, end_percent)
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@ app.registerExtension({
|
||||
name: "comfy.easyUse.imageWidgets",
|
||||
|
||||
nodeCreated(node) {
|
||||
if (["easy imageSize","easy imageSizeByLongerSide"].includes(node.comfyClass)) {
|
||||
if (["easy imageSize","easy imageSizeBySide","easy imageSizeByLongerSide"].includes(node.comfyClass)) {
|
||||
|
||||
const inputEl = document.createElement("textarea");
|
||||
inputEl.className = "comfy-multiline-input";
|
||||
@@ -29,7 +29,7 @@ app.registerExtension({
|
||||
},
|
||||
|
||||
beforeRegisterNodeDef(nodeType, nodeData, app) {
|
||||
if (["easy imageSize","easy imageSizeByLongerSide"].includes(nodeData.name)) {
|
||||
if (["easy imageSize","easy imageSizeBySide","easy imageSizeByLongerSide"].includes(nodeData.name)) {
|
||||
function populate(arr_text) {
|
||||
var text = '';
|
||||
for (let i = 0; i < arr_text.length; i++){
|
||||
|
||||
Reference in New Issue
Block a user