-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathnode_processing.py
More file actions
222 lines (192 loc) · 9.14 KB
/
Copy pathnode_processing.py
File metadata and controls
222 lines (192 loc) · 9.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
import copy
import torch
from .helpers.imgutil import tensor_to_base64
from .helpers.imgutil import tensor_image_resize_and_crop_to_multiple_of_64
class PseudoProcessEnvironmentalPrompts:
"""
Utility class for previewing environmental prompts.
Returns environmental prompt inputs unaltered.
Inputs:
env_scene (str): Scene description for the environment prompt.
env_style (str): Style description for the environment prompt.
env_negative (str): Negative prompt for the environment.
Outputs:
env_scene (str): Deep-copied scene description.
env_style (str): Deep-copied style description.
env_negative (str): Deep-copied negative prompt.
env_all (str): Concatenated string of scene, style, and negative prompt.
"""
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"env_scene": ("STRING", {"forceInput": True}),
"env_style": ("STRING", {"forceInput": True}),
"env_negative": ("STRING", {"forceInput": True}),
},
"hidden": {
"unique_id": "UNIQUE_ID",
"extra_pnginfo": "EXTRA_PNGINFO",
},
}
#INPUT_IS_LIST = False
RETURN_TYPES = ("STRING","STRING","STRING","STRING",)
RETURN_NAMES = ("env_scene","env_style","env_negative","env_all",)
FUNCTION = "notify"
OUTPUT_NODE = True
CATEGORY = "Pseudocomfy/Processing"
def notify(self, env_scene, env_style, env_negative, unique_id=None, extra_pnginfo=None):
if unique_id is not None and extra_pnginfo is not None:
# it looks like extra_pnginfo is only a list in earlier versions of comfyui
# this component might work perfectly fine without it
if (
isinstance(extra_pnginfo, list)
and len(extra_pnginfo) > 0
and isinstance(extra_pnginfo[0], dict)
and "workflow" in extra_pnginfo[0]
):
workflow = extra_pnginfo[0]["workflow"]
node = next(
(x for x in workflow["nodes"] if str(x["id"]) == str(unique_id[0])),
None,
)
if node:
node["env_scene"] = env_scene
node["env_style"] = env_style
node["env_negative"] = env_negative
else:
pass
#print("[pseudocomfy] PreviewEnvironmentalPrompts\n\tError: extra_pnginfo is not a valid list or missing 'workflow' key")
parts = [s for s in [env_scene, env_style, env_negative] if s is not None and str(s).strip() != ""]
env_all = "; ".join(parts)
return { #comfyui expects all values in ui to be wrapped in a list
"ui": {"env_scene": [env_scene], "env_style": [env_style], "env_negative": [env_negative]},
"result": (env_scene, env_style, env_negative, env_all,)
}
class PseudoProcessMaterialPrompts:
"""
Utility class for previewing material prompts
Returns inputs unaltered.
Inputs:
mat_txts_lst (list of str): List of material prompt texts.
mat_imgs_lst (list of tensor): List of image tensors as [1, H, W, 3] corresponding to the material prompts.
mat_msks_lst (list of tensor): List of mask tensors as [1, H, W] corresponding to the material prompts.
scale_msk_to (str): The target dimension for the shorter side of the given masks (options: 512, 1024).
Outputs:
mat_txts (list of str): Deep-copied list of material prompt texts.
mat_imgs (list of tensor): Deep-copied list of image tensors.
mat_msks (list of tensor): Deep-copied list of mask tensors.
mat_txts_all (str): Concatenated string of all material prompt texts.
Additional Information:
- The class encodes image and mask tensors to base64 for UI display.
- All outputs are wrapped in lists to comply with ComfyUI requirements.
- Designed for use in the "Pseudocomfy/Utils" category.
"""
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"mat_txts_lst": ("STRING", {"forceInput": True}),
"mat_imgs_lst": ("IMAGE", {"forceInput": True}),
"mat_msks_lst": ("MASK", {"forceInput": True}),
"scale_msk_to": (["512", "1024"], {"default": "1024"}),
}
}
INPUT_IS_LIST = True
OUTPUT_IS_LIST = (True,True,True,False,False,False)
RETURN_TYPES = ("STRING", "IMAGE", "MASK", "STRING","INT", "INT",)
RETURN_NAMES = ("mat_txts", "mat_imgs", "mat_msks", "mat_txts_all", "scaled_width", "scaled_height",)
FUNCTION = "func"
OUTPUT_NODE = True
CATEGORY = "Pseudocomfy/Processing"
def func(self, mat_txts_lst, mat_imgs_lst, mat_msks_lst, scale_msk_to):
print("[pseudocomfy] ProcessMaterialPrompts")
# mat inputs are expected to be lists
mat_txts = mat_txts_lst
mat_imgs = mat_imgs_lst
mat_msks = mat_msks_lst
# if scale_to is a list, use the first element
if isinstance(scale_msk_to, list) and len(scale_msk_to)>0: scale_msk_to = scale_msk_to[0]
# verify scale_to value - ComfyUI is behaving weirdly about the default value
if not scale_msk_to or scale_msk_to not in ["512", "1024"]:
scale_msk_to = "1024"
# Convert scale_to from string to int
scale_to_int = int(scale_msk_to)
if scale_to_int not in [512, 1024]:
raise ValueError(f"Invalid scale_to value: {scale_msk_to}. Expected 512 or 1024.")
# convert all image and mask tensors to base64 for UI display
mat_imgs_b64 = [tensor_to_base64(t) for t in mat_imgs]
mat_msks_b64 = [tensor_to_base64(t) for t in mat_msks]
# Resize and crop all masks to the target scale
mat_msks_resized = []
scaled_width = None
scaled_height = None
for m in mat_msks:
sw, sh, m_resized = tensor_image_resize_and_crop_to_multiple_of_64(m, scale_to_int)
mat_msks_resized.append(m_resized)
# Store the scaled dimensions from the first mask (assuming all are the same)
if scaled_width is None and scaled_height is None:
scaled_width = sw
scaled_height = sh
# concatenate all mask texts
parts = [s for s in mat_txts if s is not None and str(s).strip() != ""]
mat_txts_all = "; ".join(parts)
#print(f"\tmat_txts_all: '{mat_txts_all}'", parts)
return { #comfyui expects all values in ui to be wrapped in a list, since these are all lists we're fine.
"ui": {"mat_txts": mat_txts, "mat_imgs": mat_imgs_b64, "mat_msks": mat_msks_b64},
"result": (
copy.deepcopy(mat_txts),
copy.deepcopy(mat_imgs),
mat_msks_resized,
mat_txts_all,
)
}
class PseudoProcessImagePrompt:
"""
Utility class for scaling images and returning both the scaled image and relevant metadata.
Inputs:
img (tensor): The input image tensor, expected shape [1, H, W, 3].
scale_img_to (str): The target dimension for the shorter side of the given image ("512" or "1024").
Outputs:
scaled_width (int): The width of the scaled image (multiple of 64).
scaled_height (int): The height of the scaled image (multiple of 64).
img (tensor): The scaled and cropped image tensor.
"""
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"img": ("IMAGE", {"forceInput": True}),
"scale_img_to": (["512", "1024"], {"default": "1024"}),
}
}
RETURN_TYPES = ("INT", "INT", "IMAGE",)
RETURN_NAMES = ("scaled_width", "scaled_height", "img",)
FUNCTION = "func"
OUTPUT_NODE = True
CATEGORY = "Pseudocomfy/Processing"
def func(self, img, scale_img_to):
print(f"[pseudocomfy] ProcessImagePrompt\n\tscale_to: {scale_img_to}\n\timg: {tuple(img.shape)}")
# verify scale_to value - ComfyUI is behaving weirdly about the default value
if not scale_img_to or scale_img_to not in ["512", "1024"]:
scale_img_to = "1024"
# Convert scale_to from string to int
scale_to_int = int(scale_img_to)
if scale_to_int not in [512, 1024]:
raise ValueError(f"Invalid scale_to value: {scale_img_to}. Expected 512 or 1024.")
given_height, given_width = img.shape[1], img.shape[2]
scaled_width, scaled_height, image = tensor_image_resize_and_crop_to_multiple_of_64(img, scale_to_int)
return {
"ui": { #comfyui expects all values in ui to be wrapped in a list
"given_width": [given_width],
"given_height": [given_height],
"img": [tensor_to_base64(image)],
"scaled_width": [scaled_width],
"scaled_height": [scaled_height]
},
"result": (
scaled_width,
scaled_height,
image,
)
}