Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
44adbbe282 | ||
|
|
940ad41b15 | ||
|
|
e848a9dfb7 | ||
|
|
76653016dc | ||
|
|
9ed160123d |
@@ -228,11 +228,14 @@ This custom node helps to conveniently enhance images through Detector, Detailer
|
|||||||
|
|
||||||
|
|
||||||
### Batch/List Util
|
### Batch/List Util
|
||||||
* `Image batch To Image List` - Convert Image batch to Image List
|
* `Image Batch to Image List` - Convert Image batch to Image List
|
||||||
- You can use images generated in a multi batch to handle them
|
- You can use images generated in a multi batch to handle them
|
||||||
|
* `Image List to Image Batch` - Convert Image List to Image Batch
|
||||||
* `Make Image List` - Convert multiple images into a single image list
|
* `Make Image List` - Convert multiple images into a single image list
|
||||||
* `Make Image Batch` - Convert multiple images into a single image batch
|
* `Make Image Batch` - Convert multiple images into a single image batch
|
||||||
- The input of images can be scaled up as needed
|
- The input of images can be scaled up as needed
|
||||||
|
* `Masks to Mask List`, `Mask List to Masks`, `Make Mask List`, `Make Mask Batch` - It has the same functionality as the nodes above, but uses mask as input instead of image.
|
||||||
|
* `Flatten Mask Batch` - Flattens a Mask Batch into a single Mask. Normal operation is not guaranteed for non-binary masks.
|
||||||
|
|
||||||
|
|
||||||
### Logics (experimental)
|
### Logics (experimental)
|
||||||
|
|||||||
+11
-3
@@ -161,6 +161,7 @@ NODE_CLASS_MAPPINGS = {
|
|||||||
"ImpactSegsAndMask": SegsBitwiseAndMask,
|
"ImpactSegsAndMask": SegsBitwiseAndMask,
|
||||||
"ImpactSegsAndMaskForEach": SegsBitwiseAndMaskForEach,
|
"ImpactSegsAndMaskForEach": SegsBitwiseAndMaskForEach,
|
||||||
"EmptySegs": EmptySEGS,
|
"EmptySegs": EmptySEGS,
|
||||||
|
"ImpactFlattenMask": FlattenMask,
|
||||||
|
|
||||||
"MediaPipeFaceMeshToSEGS": MediaPipeFaceMeshToSEGS,
|
"MediaPipeFaceMeshToSEGS": MediaPipeFaceMeshToSEGS,
|
||||||
"MaskToSEGS": MaskToSEGS,
|
"MaskToSEGS": MaskToSEGS,
|
||||||
@@ -249,6 +250,8 @@ NODE_CLASS_MAPPINGS = {
|
|||||||
"ImpactImageBatchToImageList": ImageBatchToImageList,
|
"ImpactImageBatchToImageList": ImageBatchToImageList,
|
||||||
"ImpactMakeImageList": MakeImageList,
|
"ImpactMakeImageList": MakeImageList,
|
||||||
"ImpactMakeImageBatch": MakeImageBatch,
|
"ImpactMakeImageBatch": MakeImageBatch,
|
||||||
|
"ImpactMakeMaskList": MakeMaskList,
|
||||||
|
"ImpactMakeMaskBatch": MakeMaskBatch,
|
||||||
|
|
||||||
"RegionalSampler": RegionalSampler,
|
"RegionalSampler": RegionalSampler,
|
||||||
"RegionalSamplerAdvanced": RegionalSamplerAdvanced,
|
"RegionalSamplerAdvanced": RegionalSamplerAdvanced,
|
||||||
@@ -332,6 +335,7 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
|||||||
"BitwiseAndMask": "Pixelwise(MASK & MASK)",
|
"BitwiseAndMask": "Pixelwise(MASK & MASK)",
|
||||||
"SubtractMask": "Pixelwise(MASK - MASK)",
|
"SubtractMask": "Pixelwise(MASK - MASK)",
|
||||||
"AddMask": "Pixelwise(MASK + MASK)",
|
"AddMask": "Pixelwise(MASK + MASK)",
|
||||||
|
"ImpactFlattenMask": "Flatten Mask Batch",
|
||||||
"DetailerForEach": "Detailer (SEGS)",
|
"DetailerForEach": "Detailer (SEGS)",
|
||||||
"DetailerForEachPipe": "Detailer (SEGS/pipe)",
|
"DetailerForEachPipe": "Detailer (SEGS/pipe)",
|
||||||
"DetailerForEachDebug": "DetailerDebug (SEGS)",
|
"DetailerForEachDebug": "DetailerDebug (SEGS)",
|
||||||
@@ -400,12 +404,16 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
|||||||
"ImpactInversedSwitch": "Inversed Switch (Any)",
|
"ImpactInversedSwitch": "Inversed Switch (Any)",
|
||||||
"ImpactExecutionOrderController": "Execution Order Controller",
|
"ImpactExecutionOrderController": "Execution Order Controller",
|
||||||
|
|
||||||
"MasksToMaskList": "Masks to Mask List",
|
"MasksToMaskList": "Mask Batch to Mask List",
|
||||||
"MaskListToMaskBatch": "Mask List to Masks",
|
"MaskListToMaskBatch": "Mask List to Mask Batch",
|
||||||
"ImpactImageBatchToImageList": "Image batch to Image List",
|
"ImpactImageBatchToImageList": "Image Batch to Image List",
|
||||||
"ImageListToImageBatch": "Image List to Image Batch",
|
"ImageListToImageBatch": "Image List to Image Batch",
|
||||||
|
|
||||||
"ImpactMakeImageList": "Make Image List",
|
"ImpactMakeImageList": "Make Image List",
|
||||||
"ImpactMakeImageBatch": "Make Image Batch",
|
"ImpactMakeImageBatch": "Make Image Batch",
|
||||||
|
"ImpactMakeMaskList": "Make Mask List",
|
||||||
|
"ImpactMakeMaskBatch": "Make Mask Batch",
|
||||||
|
|
||||||
"ImpactStringSelector": "String Selector",
|
"ImpactStringSelector": "String Selector",
|
||||||
"StringListToString": "String List to String",
|
"StringListToString": "String List to String",
|
||||||
"WildcardPromptFromString": "Wildcard Prompt from String",
|
"WildcardPromptFromString": "Wildcard Prompt from String",
|
||||||
|
|||||||
+7
-1
@@ -237,7 +237,7 @@ app.registerExtension({
|
|||||||
if(nodeData.name == "ImpactControlBridge") {
|
if(nodeData.name == "ImpactControlBridge") {
|
||||||
const onConnectionsChange = nodeType.prototype.onConnectionsChange;
|
const onConnectionsChange = nodeType.prototype.onConnectionsChange;
|
||||||
nodeType.prototype.onConnectionsChange = function (type, index, connected, link_info) {
|
nodeType.prototype.onConnectionsChange = function (type, index, connected, link_info) {
|
||||||
if(!link_info || this.inputs[0].type != '*')
|
if(index != 0 || !link_info || this.inputs[0].type != '*')
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// assign type
|
// assign type
|
||||||
@@ -393,6 +393,7 @@ app.registerExtension({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (nodeData.name === 'ImpactMakeImageList' || nodeData.name === 'ImpactMakeImageBatch' ||
|
if (nodeData.name === 'ImpactMakeImageList' || nodeData.name === 'ImpactMakeImageBatch' ||
|
||||||
|
nodeData.name === 'ImpactMakeMaskList' || nodeData.name === 'ImpactMakeMaskBatch' ||
|
||||||
nodeData.name === 'CombineRegionalPrompts' ||
|
nodeData.name === 'CombineRegionalPrompts' ||
|
||||||
nodeData.name === 'ImpactCombineConditionings' || nodeData.name === 'ImpactConcatConditionings' ||
|
nodeData.name === 'ImpactCombineConditionings' || nodeData.name === 'ImpactConcatConditionings' ||
|
||||||
nodeData.name === 'ImpactSEGSConcat' ||
|
nodeData.name === 'ImpactSEGSConcat' ||
|
||||||
@@ -405,6 +406,11 @@ app.registerExtension({
|
|||||||
input_name = "image";
|
input_name = "image";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'ImpactMakeMaskList':
|
||||||
|
case 'ImpactMakeMaskBatch':
|
||||||
|
input_name = "mask";
|
||||||
|
break;
|
||||||
|
|
||||||
case 'ImpactSEGSConcat':
|
case 'ImpactSEGSConcat':
|
||||||
input_name = "segs";
|
input_name = "segs";
|
||||||
break;
|
break;
|
||||||
|
|||||||
+11
-7
@@ -6,11 +6,15 @@ let refresh_btn2 = document.querySelector('button[title="Refresh widgets in node
|
|||||||
|
|
||||||
let orig = refresh_btn.onclick;
|
let orig = refresh_btn.onclick;
|
||||||
|
|
||||||
refresh_btn.onclick = function() {
|
if(refresh_btn) {
|
||||||
orig();
|
refresh_btn.onclick = function() {
|
||||||
api.fetchApi('/impact/wildcards/refresh');
|
orig();
|
||||||
};
|
api.fetchApi('/impact/wildcards/refresh');
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
refresh_btn2.addEventListener('click', function() {
|
if(refresh_btn2) {
|
||||||
api.fetchApi('/impact/wildcards/refresh');
|
refresh_btn2?.addEventListener('click', function() {
|
||||||
});
|
api.fetchApi('/impact/wildcards/refresh');
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -20,7 +20,7 @@ class PreviewBridge:
|
|||||||
"image": ("STRING", {"default": ""}),
|
"image": ("STRING", {"default": ""}),
|
||||||
},
|
},
|
||||||
"optional": {
|
"optional": {
|
||||||
"block": ("BOOLEAN", {"default": True, "label_on": "if_empty_mask", "label_off": "never", "tooltip": "is_empty_mask: If the mask is empty, the execution is stopped.\nnever: The execution is never stopped."})
|
"block": ("BOOLEAN", {"default": False, "label_on": "if_empty_mask", "label_off": "never", "tooltip": "is_empty_mask: If the mask is empty, the execution is stopped.\nnever: The execution is never stopped."})
|
||||||
},
|
},
|
||||||
"hidden": {"unique_id": "UNIQUE_ID", "extra_pnginfo": "EXTRA_PNGINFO"},
|
"hidden": {"unique_id": "UNIQUE_ID", "extra_pnginfo": "EXTRA_PNGINFO"},
|
||||||
}
|
}
|
||||||
@@ -196,7 +196,7 @@ class PreviewBridgeLatent:
|
|||||||
},
|
},
|
||||||
"optional": {
|
"optional": {
|
||||||
"vae_opt": ("VAE", ),
|
"vae_opt": ("VAE", ),
|
||||||
"block": ("BOOLEAN", {"default": True, "label_on": "if_empty_mask", "label_off": "never", "tooltip": "is_empty_mask: If the mask is empty, the execution is stopped.\nnever: The execution is never stopped. Instead, it returns a white mask."})
|
"block": ("BOOLEAN", {"default": False, "label_on": "if_empty_mask", "label_off": "never", "tooltip": "is_empty_mask: If the mask is empty, the execution is stopped.\nnever: The execution is never stopped. Instead, it returns a white mask."})
|
||||||
},
|
},
|
||||||
"hidden": {"unique_id": "UNIQUE_ID", "prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO"},
|
"hidden": {"unique_id": "UNIQUE_ID", "prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO"},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import configparser
|
import configparser
|
||||||
import os
|
import os
|
||||||
|
|
||||||
version_code = [7, 4, 2]
|
version_code = [7, 5]
|
||||||
version = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '')
|
version = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '')
|
||||||
|
|
||||||
dependency_version = 22
|
dependency_version = 22
|
||||||
|
|||||||
@@ -1696,6 +1696,25 @@ class ToBinaryMask:
|
|||||||
return (mask,)
|
return (mask,)
|
||||||
|
|
||||||
|
|
||||||
|
class FlattenMask:
|
||||||
|
@classmethod
|
||||||
|
def INPUT_TYPES(s):
|
||||||
|
return {"required": {
|
||||||
|
"masks": ("MASK",),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN_TYPES = ("MASK",)
|
||||||
|
FUNCTION = "doit"
|
||||||
|
|
||||||
|
CATEGORY = "ImpactPack/Operation"
|
||||||
|
|
||||||
|
def doit(self, masks):
|
||||||
|
masks = utils.make_3d_mask(masks)
|
||||||
|
masks = utils.flatten_mask(masks)
|
||||||
|
return (masks,)
|
||||||
|
|
||||||
|
|
||||||
class BitwiseAndMask:
|
class BitwiseAndMask:
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def INPUT_TYPES(s):
|
||||||
|
|||||||
@@ -392,6 +392,26 @@ class ImageBatchToImageList:
|
|||||||
return (images, )
|
return (images, )
|
||||||
|
|
||||||
|
|
||||||
|
class MakeMaskList:
|
||||||
|
@classmethod
|
||||||
|
def INPUT_TYPES(s):
|
||||||
|
return {"required": {"mask1": ("MASK",), }}
|
||||||
|
|
||||||
|
RETURN_TYPES = ("MASK",)
|
||||||
|
OUTPUT_IS_LIST = (True,)
|
||||||
|
FUNCTION = "doit"
|
||||||
|
|
||||||
|
CATEGORY = "ImpactPack/Util"
|
||||||
|
|
||||||
|
def doit(self, **kwargs):
|
||||||
|
masks = []
|
||||||
|
|
||||||
|
for k, v in kwargs.items():
|
||||||
|
masks.append(v)
|
||||||
|
|
||||||
|
return (masks, )
|
||||||
|
|
||||||
|
|
||||||
class MakeImageList:
|
class MakeImageList:
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def INPUT_TYPES(s):
|
||||||
@@ -437,6 +457,31 @@ class MakeImageBatch:
|
|||||||
return (image1,)
|
return (image1,)
|
||||||
|
|
||||||
|
|
||||||
|
class MakeMaskBatch:
|
||||||
|
@classmethod
|
||||||
|
def INPUT_TYPES(s):
|
||||||
|
return {"required": {"mask1": ("MASK",), }}
|
||||||
|
|
||||||
|
RETURN_TYPES = ("MASK",)
|
||||||
|
FUNCTION = "doit"
|
||||||
|
|
||||||
|
CATEGORY = "ImpactPack/Util"
|
||||||
|
|
||||||
|
def doit(self, **kwargs):
|
||||||
|
mask1 = kwargs['mask1']
|
||||||
|
del kwargs['mask1']
|
||||||
|
masks = [utils.make_3d_mask(value) for value in kwargs.values()]
|
||||||
|
|
||||||
|
if len(masks) == 0:
|
||||||
|
return (mask1,)
|
||||||
|
else:
|
||||||
|
for mask2 in masks:
|
||||||
|
if mask1.shape[1:] != mask2.shape[1:]:
|
||||||
|
mask2 = comfy.utils.common_upscale(mask2.movedim(-1, 1), mask1.shape[2], mask1.shape[1], "lanczos", "center").movedim(1, -1)
|
||||||
|
mask1 = torch.cat((mask1, mask2), dim=0)
|
||||||
|
return (mask1,)
|
||||||
|
|
||||||
|
|
||||||
class ReencodeLatent:
|
class ReencodeLatent:
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def INPUT_TYPES(s):
|
||||||
|
|||||||
@@ -5,8 +5,7 @@ import numpy as np
|
|||||||
import folder_paths
|
import folder_paths
|
||||||
import nodes
|
import nodes
|
||||||
from . import config
|
from . import config
|
||||||
from PIL import Image, ImageFilter
|
from PIL import Image
|
||||||
from scipy.ndimage import zoom
|
|
||||||
import comfy
|
import comfy
|
||||||
|
|
||||||
|
|
||||||
@@ -579,6 +578,14 @@ def apply_mask_alpha_to_pil(decoded_pil, mask):
|
|||||||
return decoded_rgba
|
return decoded_rgba
|
||||||
|
|
||||||
|
|
||||||
|
def flatten_mask(all_masks):
|
||||||
|
merged_mask = (all_masks[0] * 255).to(torch.uint8)
|
||||||
|
for mask in all_masks[1:]:
|
||||||
|
merged_mask |= (mask * 255).to(torch.uint8)
|
||||||
|
|
||||||
|
return merged_mask
|
||||||
|
|
||||||
|
|
||||||
def try_install_custom_node(custom_node_url, msg):
|
def try_install_custom_node(custom_node_url, msg):
|
||||||
try:
|
try:
|
||||||
import cm_global
|
import cm_global
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "comfyui-impact-pack"
|
name = "comfyui-impact-pack"
|
||||||
description = "This extension offers various detector nodes and detailer nodes that allow you to configure a workflow that automatically enhances facial details. And provide iterative upscaler."
|
description = "This extension offers various detector nodes and detailer nodes that allow you to configure a workflow that automatically enhances facial details. And provide iterative upscaler."
|
||||||
version = "7.4.2"
|
version = "7.5"
|
||||||
license = { file = "LICENSE.txt" }
|
license = { file = "LICENSE.txt" }
|
||||||
dependencies = ["segment-anything", "scikit-image", "piexif", "transformers", "opencv-python-headless", "GitPython", "scipy>=1.11.4"]
|
dependencies = ["segment-anything", "scikit-image", "piexif", "transformers", "opencv-python-headless", "GitPython", "scipy>=1.11.4"]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user