started for dynamic inputs
This commit is contained in:
+19
-10
@@ -1,19 +1,28 @@
|
||||
from .nodes import FitSize, FitSizeFromImage, FitResizeImage, FitResizeLatent, LoadToFitResizeLatent
|
||||
from .nodes import *
|
||||
from .startup_utils import symlink_web_dir
|
||||
|
||||
# A dictionary that contains all nodes you want to export with their names
|
||||
# NOTE: names should be globally unique
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"Fit Size From Int": FitSize,
|
||||
"Fit Size From Image": FitSizeFromImage,
|
||||
"Fit Image And Resize": FitResizeLatent,
|
||||
"Load Image And Resize To Fit": LoadToFitResizeLatent,
|
||||
"FS: Fit Size From Int": FitSize,
|
||||
"FS: Fit Size From Image": FitSizeFromImage,
|
||||
"FS: Fit Image And Resize": FitResizeLatent,
|
||||
"FS: Load Image And Resize To Fit": LoadToFitResizeLatent,
|
||||
"FS: Pick Image From Batch": RandomImageFromBatch,
|
||||
"FS: Crop Image Into Even Pieces": CropImageIntoEvenPieces,
|
||||
}
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"Fit Size From Int": "Fit Size From Int",
|
||||
"Fit Size From Image": "Fit Size From Image",
|
||||
"Fit Image And Resize": "Fit Image And Resize",
|
||||
"Load Image And Resize To Fit": "Load Image And Resize To Fit",
|
||||
"FS: Fit Size From Int": "Fit Size From Int",
|
||||
"FS: Fit Size From Image": "Fit Size From Image",
|
||||
"FS: Fit Image And Resize": "Fit Image And Resize",
|
||||
"FS: Load Image And Resize To Fit": "Load Image And Resize To Fit",
|
||||
"FS: Pick Image From Batch": "Pick Image From Batch",
|
||||
"FS: Crop Image Into Even Pieces": "Crop Image Into Even Pieces",
|
||||
}
|
||||
|
||||
__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS']
|
||||
__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS']
|
||||
|
||||
EXTENSION_NAME = "Fitsize"
|
||||
|
||||
symlink_web_dir("js", EXTENSION_NAME)
|
||||
@@ -110,7 +110,7 @@ class FitSize:
|
||||
RETURN_NAMES = ("Fit Width", "Fit Height", "Aspect Ratio")
|
||||
FUNCTION = "fit_to_size"
|
||||
|
||||
CATEGORY = "Fitsize"
|
||||
CATEGORY = "Fitsize/Numbers"
|
||||
|
||||
def fit_to_size (self, original_width, original_height, max_size, upscale="false"):
|
||||
values = get_max_size(original_width, original_height, max_size, upscale)
|
||||
@@ -134,7 +134,7 @@ class FitSizeFromImage:
|
||||
RETURN_NAMES = ("Fit Width", "Fit Height", "Aspect Ratio")
|
||||
FUNCTION = "fit_to_size_from_image"
|
||||
|
||||
CATEGORY = "Fitsize"
|
||||
CATEGORY = "Fitsize/Numbers"
|
||||
|
||||
def fit_to_size_from_image (self, image, max_size, upscale="false"):
|
||||
size = get_image_size(image)
|
||||
@@ -160,7 +160,7 @@ class FitResizeImage:
|
||||
RETURN_NAMES = ("Image","Fit Width", "Fit Height", "Aspect Ratio")
|
||||
FUNCTION = "fit_resize_image"
|
||||
|
||||
CATEGORY = "Fitsize"
|
||||
CATEGORY = "Fitsize/Image"
|
||||
|
||||
def fit_resize_image (self, image, max_size=768, resampling="bicubic", upscale="false", latent=False):
|
||||
size = get_image_size(image)
|
||||
@@ -208,7 +208,7 @@ class FitResizeLatent():
|
||||
)
|
||||
FUNCTION = "fit_resize_latent"
|
||||
|
||||
CATEGORY = "Fitsize"
|
||||
CATEGORY = "Fitsize/Image"
|
||||
|
||||
def fit_resize_latent (self, image, vae, max_size=768, resampling="bicubic", upscale="false", batch_size=1, add_noise=0.0):
|
||||
|
||||
@@ -252,7 +252,7 @@ class LoadToFitResizeLatent():
|
||||
)
|
||||
FUNCTION = "fit_resize_latent"
|
||||
|
||||
CATEGORY = "Fitsize"
|
||||
CATEGORY = "Fitsize/Image"
|
||||
|
||||
@staticmethod
|
||||
def load_image(image):
|
||||
@@ -299,4 +299,103 @@ class LoadToFitResizeLatent():
|
||||
new_height,
|
||||
aspect_ratio,
|
||||
mask,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class CropImageIntoEvenPieces:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {
|
||||
"required": {
|
||||
"image": ("IMAGE",),
|
||||
"rows": ("INT", {"default": 3, "min": 1, "max": 32, "step": 1,}),
|
||||
"columns": ("INT", {"default": 1, "min": 1, "max": 32, "step": 1,}),
|
||||
},
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("IMAGE",)
|
||||
|
||||
FUNCTION = "run"
|
||||
|
||||
CATEGORY = "Fitsize/Image"
|
||||
|
||||
def run(self, image, rows, columns):
|
||||
|
||||
if rows < 1:
|
||||
rows = 1
|
||||
if columns < 1:
|
||||
columns = 1
|
||||
|
||||
w = image.shape[2] # width
|
||||
h = image.shape[1] # height
|
||||
|
||||
crop_width = int(w / columns)
|
||||
crop_height = int(h / rows)
|
||||
|
||||
image = image.numpy()
|
||||
|
||||
pieces = []
|
||||
for i in range(rows):
|
||||
for j in range(columns):
|
||||
y = i * crop_height
|
||||
x = j * crop_width
|
||||
|
||||
crop = image[: , y : y + crop_height , x : x + crop_width , :]
|
||||
pieces.append(torch.from_numpy(crop))
|
||||
# image[:, y : y + height, x : x + width, :]
|
||||
|
||||
return (torch.cat(pieces, dim=0), )
|
||||
|
||||
|
||||
|
||||
class RandomImageFromBatch:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {
|
||||
"required": {
|
||||
"images": ("IMAGE", ),
|
||||
"seed": ("INT", {"default": 0}),
|
||||
"start_index": ("INT", {"default": -1, "min": -1, "max": 32, "step": 1,}),
|
||||
"select_amount": ("INT", {"default": 1, "min": 1, "max": 32, "step": 1,}),
|
||||
},
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("IMAGE",)
|
||||
|
||||
FUNCTION = "run"
|
||||
|
||||
CATEGORY = "Fitsize/Image"
|
||||
|
||||
def run(self, images, seed, start_index, select_amount):
|
||||
|
||||
# if type(images) == torch.Tensor:
|
||||
# images = images.numpy()
|
||||
|
||||
if start_index == -1:
|
||||
start_index = np.random.randint(0, images.shape[0])
|
||||
if start_index >= images.shape[0]:
|
||||
start_index = images.shape[0]-1
|
||||
|
||||
if select_amount > images.shape[0]:
|
||||
select_amount = images.shape[0]
|
||||
if select_amount < 1:
|
||||
select_amount = 1
|
||||
|
||||
|
||||
print(
|
||||
f"RandomImageFromBatch: start_index {start_index},",
|
||||
f"select_amount {select_amount}",
|
||||
f"total_images {images.shape[0]}",)
|
||||
|
||||
selected = images[start_index:start_index + select_amount]
|
||||
|
||||
print(f"RandomImageFromBatch: selected {selected.shape[0]} images")
|
||||
|
||||
return (selected, )
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
import folder_paths
|
||||
|
||||
# from: https://github.com/M1kep/ComfyLiterals
|
||||
|
||||
|
||||
def symlink_web_dir(local_path, extension_name):
|
||||
comfy_web_ext_root = Path(os.path.join(folder_paths.base_path, "web", "extensions"))
|
||||
target_dir = Path(os.path.join(comfy_web_ext_root, extension_name))
|
||||
extension_path = Path(__file__).parent.resolve()
|
||||
|
||||
if target_dir.exists():
|
||||
print(f"Web extensions folder found at {target_dir}")
|
||||
elif comfy_web_ext_root.exists():
|
||||
try:
|
||||
os.symlink((os.path.join(extension_path, local_path)), target_dir)
|
||||
except OSError as e: # OSError
|
||||
print(
|
||||
f"Error:\n{e}\n"
|
||||
f"Failed to create symlink to {target_dir}. Please copy the folder manually.\n"
|
||||
f"Source: {os.path.join(extension_path, local_path)}\n"
|
||||
f"Target: {target_dir}"
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Unexpected error:\n{e}")
|
||||
else:
|
||||
print(
|
||||
f"Failed to find comfy root automatically, please copy the folder {os.path.join(extension_path, 'web')} manually in the web/extensions folder of ComfyUI"
|
||||
)
|
||||
Reference in New Issue
Block a user