diff --git a/src/comfyui_ino_nodes/node_helpers/image_helper.py b/src/comfyui_ino_nodes/node_helpers/image_helper.py index 3189ba9..6f17d9e 100644 --- a/src/comfyui_ino_nodes/node_helpers/image_helper.py +++ b/src/comfyui_ino_nodes/node_helpers/image_helper.py @@ -460,6 +460,84 @@ class InoImageToBase64: return (False, str(e)) +class InoImagesFromFolderToReferenceLatent(io.ComfyNode): + @classmethod + def define_schema(cls): + return io.Schema( + node_id="InoImagesFromFolderToReferenceLatent", + display_name="Ino Images From Folder To Reference Latent", + category="InoNodes", + inputs=[ + io.Combo.Input("parent_folder", options=["input", "output", "temp"]), + io.String.Input("folder"), + io.Int.Input("load_cap", default=0, min=0, max=10000), + io.Int.Input("skip_from_first", default=0, min=0, max=10000), + io.Combo.Input("upscale_method", options=["nearest-exact", "bilinear", "area", "bicubic", "lanczos"]), + io.Float.Input("megapixels", default=1.0, min=0.01, max=16.0, step=0.01), + io.Int.Input("resolution_steps", default=1, min=1, max=256), + io.Vae.Input("vae"), + io.Conditioning.Input("conditioning"), + ], + outputs=[ + io.Boolean.Output(display_name="success"), + io.Image.Output(display_name="images", is_output_list=True), + io.Int.Output(display_name="number_of_images"), + io.Latent.Output(display_name="latents", is_output_list=True), + io.Conditioning.Output(display_name="conditioning"), + ], + ) + + @classmethod + def execute(cls, parent_folder, folder, load_cap, skip_from_first, + upscale_method, megapixels, resolution_steps, + vae, conditioning): + from comfy_extras.nodes_dataset import load_and_process_images + from comfy_extras.nodes_post_processing import ImageScaleToTotalPixels + from comfy_extras.nodes_edit_model import ReferenceLatent + from nodes import VAEEncode + + if parent_folder == "input": + sub_input_dir = os.path.join(folder_paths.get_input_directory(), folder) + elif parent_folder == "output": + sub_input_dir = os.path.join(folder_paths.get_output_directory(), folder) + else: + sub_input_dir = os.path.join(folder_paths.get_temp_directory(), folder) + + valid_extensions = [".png", ".jpg", ".jpeg", ".webp"] + image_files = [ + f for f in os.listdir(sub_input_dir) + if any(f.lower().endswith(ext) for ext in valid_extensions) + ] + image_files = sorted(image_files) + + skip_from_first = max(0, int(skip_from_first)) + load_cap = max(0, int(load_cap)) + + if skip_from_first: + image_files = image_files[skip_from_first:] + if load_cap > 0: + image_files = image_files[:load_cap] + + if not image_files: + return io.NodeOutput(False, [], 0, [], conditioning) + + output_images = load_and_process_images(image_files, sub_input_dir) + num_images = len(output_images) + + vae_encoder = VAEEncode() + latents = [] + cond = conditioning + + for img in output_images: + single = img.unsqueeze(0) + scaled = ImageScaleToTotalPixels.execute(single, upscale_method, megapixels, resolution_steps)[0] + latent = vae_encoder.encode(vae, scaled)[0] + latents.append(latent) + cond = ReferenceLatent.execute(cond, latent)[0] + + return io.NodeOutput(True, output_images, num_images, latents, cond) + + LOCAL_NODE_CLASS = { "InoSaveImages": InoSaveImages, "InoImageResizeByLongerSideV1": InoImageResizeByLongerSideV1, @@ -468,6 +546,7 @@ LOCAL_NODE_CLASS = { "InoOnImageListCompleted": InoOnImageListCompleted, "InoCropImageByBox": InoCropImageByBox, "InoImageToBase64": InoImageToBase64, + "InoImagesFromFolderToReferenceLatent": InoImagesFromFolderToReferenceLatent, } LOCAL_NODE_NAME = { "InoSaveImages": "Ino Save Images", @@ -477,4 +556,5 @@ LOCAL_NODE_NAME = { "InoOnImageListCompleted": "Ino On Image List Completed", "InoCropImageByBox": "Ino Crop Image By Box", "InoImageToBase64": "Ino Image To Base64", + "InoImagesFromFolderToReferenceLatent": "Ino Images From Folder To Reference Latent", }