From fdcc0c25d3ddadb411eec8a3d0670c694637e838 Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Wed, 28 Jun 2023 23:24:28 +0900 Subject: [PATCH] add SEGSToImageList bugfix: ImageReceiver/LatentReceiver crash on VALIDATE_INPUT bugfix: ImageSender/LatentSender doesn't work occasionally --- README.md | 2 ++ __init__.py | 1 + js/impact-pack.js | 26 ++++------------------ modules/impact/config.py | 2 +- modules/impact/impact_pack.py | 41 ++++++++++++++++++++++++++++++++--- 5 files changed, 46 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 7050c70..4a21fe4 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,8 @@ This custom node helps to conveniently enhance images through Detector, Detailer * SEGSPaste - Pastes the results of SEGS onto the original image. * SEGSPreview - Provides a preview of SEGS. * This option is used to preview the improved image through ```SEGSDetailer``` before merging it into the original. Prior to going through ```SEGSDetailer```, SEGS only contains mask information without image information. If fallback_image_opt is connected to the original image, SEGS without image information will generate a preview using the original image. However, if SEGS already contains image information, fallback_image_opt will be ignored. +* SEGSToImageList - Convert SEGS To Image List + * If SEGS is not present, the application will stop with an error unless [PR 731](https://github.com/comfyanonymous/ComfyUI/pull/731) from is applied. * Pipe nodes * ToDetailerPipe, FromDetailerPipe - These nodes are used to bundle multiple inputs used in the detailer, such as models and vae, ..., into a single DETAILER_PIPE or extract the elements that are bundled in the DETAILER_PIPE. diff --git a/__init__.py b/__init__.py index 5cd7f83..54b6b14 100644 --- a/__init__.py +++ b/__init__.py @@ -156,6 +156,7 @@ NODE_CLASS_MAPPINGS = { "SEGSDetailer": SEGSDetailer, "SEGSPaste": SEGSPaste, "SEGSPreview": SEGSPreview, + "SEGSToImageList": SEGSToImageList, "MaskPainter": impact.legacy_nodes.MaskPainter, "MMDetLoader": impact.legacy_nodes.MMDetLoader, diff --git a/js/impact-pack.js b/js/impact-pack.js index 1216a6c..2f58753 100644 --- a/js/impact-pack.js +++ b/js/impact-pack.js @@ -144,36 +144,18 @@ function latentSendHandler(event) { } } -var progressEventRegistered = false; -var imgSendEventRegistered = false; -var latentSendEventRegistered = false; const impactProgressBadge = new ImpactProgressBadge(); +api.addEventListener("img-send", imgSendHandler); +api.addEventListener("latent-send", latentSendHandler); +api.addEventListener("executed", progressExecuteHandler); + app.registerExtension({ name: "Comfy.Impack", loadedGraphNode(node, app) { if (node.comfyClass == "PreviewBridge" || node.comfyClass == "MaskPainter") { - if (!progressEventRegistered) { - api.addEventListener("executed", progressExecuteHandler); - progressEventRegistered = true; - } - input_dirty[node.id + ""] = true; } - - if (node.comfyClass == "ImageSender") { - if (!imgSendEventRegistered) { - api.addEventListener("img-send", imgSendHandler); - imgSendEventRegistered = true; - } - } - - if (node.comfyClass == "LatentSender") { - if (!latentSendEventRegistered) { - api.addEventListener("latent-send", latentSendHandler); - latentSendEventRegistered = true; - } - } }, async beforeRegisterNodeDef(nodeType, nodeData, app) { diff --git a/modules/impact/config.py b/modules/impact/config.py index dca7118..cbd5ee4 100644 --- a/modules/impact/config.py +++ b/modules/impact/config.py @@ -1,7 +1,7 @@ import configparser import os -version = "V2.16.3" +version = "V2.16.4" dependency_version = 1 diff --git a/modules/impact/impact_pack.py b/modules/impact/impact_pack.py index 16bd896..811c746 100644 --- a/modules/impact/impact_pack.py +++ b/modules/impact/impact_pack.py @@ -259,7 +259,7 @@ class SEGSPreview: RETURN_TYPES = () FUNCTION = "doit" - CATEGORY = "ImpactPack/Detailer" + CATEGORY = "ImpactPack/Util" OUTPUT_NODE = True @@ -291,6 +291,41 @@ class SEGSPreview: return {"ui": {"images": results}} +class SEGSToImageList: + @classmethod + def INPUT_TYPES(s): + return {"required": { + "segs": ("SEGS", ), + }, + "optional": { + "fallback_image_opt": ("IMAGE", ), + } + } + + RETURN_TYPES = ("IMAGE",) + OUTPUT_IS_LIST = (True,) + FUNCTION = "doit" + + CATEGORY = "ImpactPack/Util" + + OUTPUT_NODE = True + + def doit(self, segs, fallback_image_opt): + results = list() + + for seg in segs[1]: + if seg.cropped_image is not None: + cropped_image = seg.cropped_image + elif fallback_image_opt is not None: + # take from original image + cropped_image = crop_image(fallback_image_opt, seg.crop_region) + + cropped_image = torch.from_numpy(cropped_image) + results.append(cropped_image) + + return (results,) + + class DetailerForEach: @classmethod def INPUT_TYPES(s): @@ -1559,7 +1594,7 @@ class ImageReceiver(nodes.LoadImage): @classmethod def VALIDATE_INPUTS(s, image, link_id): - if not folder_paths.exists_annotated_filepath(image) or image.startswith("/") or image.contains(".."): + if not folder_paths.exists_annotated_filepath(image) or image.startswith("/") or ".." in image: return "Invalid image file: {}".format(image) return True @@ -1670,7 +1705,7 @@ class LatentReceiver: @classmethod def VALIDATE_INPUTS(s, latent, link_id): - if not folder_paths.exists_annotated_filepath(latent) or latent.startswith("/") or latent.contains(".."): + if not folder_paths.exists_annotated_filepath(latent) or latent.startswith("/") or ".." in latent.contains: return "Invalid latent file: {}".format(latent) return True