diff --git a/__init__.py b/__init__.py index 1d42edb..e8cc23b 100644 --- a/__init__.py +++ b/__init__.py @@ -22,7 +22,13 @@ from .AEMatter import (load_AEMatter_Model, run_AEMatter_inference) from .light_layer import main_light_layer -from .image_stack import H_Stack_Images +from .image_stack import ( + H_Stack_Images, + SaveImage_absolute, + SaveText_absolute, + Wait_And_Read_File, +) + def from_torch_image(image): @@ -3742,7 +3748,10 @@ NODE_CLASS_MAPPINGS = { "tri3d_fill_mask": TRI3D_fill_mask, "tri3d_is_only_trouser": TRI3D_is_only_trouser, "tri3d_extract_facer_mask":TRI3D_extract_facer_mask, - "tri3d_H_Stack_Images": H_Stack_Images + "tri3d_H_Stack_Images": H_Stack_Images, + "tri3d_SaveImage_absolute":SaveImage_absolute, + "tri3d_SaveText_absolute":SaveText_absolute, + "tri3d_Wait_And_Read_File":Wait_And_Read_File, } @@ -3804,4 +3813,7 @@ NODE_DISPLAY_NAME_MAPPINGS = { "tri3d_is_only_trouser": "Is only trouser" + " v" + VERSION, "tri3d_extract_facer_mask": "Extract facer mask" + " v" + VERSION, "tri3d_H_Stack_Images": "Stack images for cat vton with flux" + " v" + VERSION, + "tri3d_SaveImage_absolute": "Save image to an absolute path and provide text optional to control execution order" + " v" + VERSION, + "tri3d_SaveText_absolute": "Save text to an absolute path and provide text optional to control execution order " + " v" + VERSION, + "tri3d_Wait_And_Read_File": "Wait and read text file, optional control from text " + " v" + VERSION, } diff --git a/image_stack.py b/image_stack.py index 5e91251..03b9b29 100755 --- a/image_stack.py +++ b/image_stack.py @@ -1,6 +1,20 @@ #!/usr/bin/python3 -import torch + +from PIL import Image, ImageOps, ImageSequence, ImageFile +from PIL.PngImagePlugin import PngInfo import cv2 +import hashlib +import json +import logging +import math +import numpy as np +import os +import random +import safetensors.torch +import sys +import time +import torch +import traceback def load_image(path): @@ -55,3 +69,135 @@ class H_Stack_Images: def test(self, image_L, image_R): return (do_stack(img1=image_L[0], img2=image_R[0]).unsqueeze(0), ) + + +class SaveImage_absolute: + + def __init__(self): + pass + + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "images": ("IMAGE", { + "tooltip": "The images to save." + }), + "absolute_filename": ("STRING", { + "default": + "image.png", + "tooltip": + "The absolute path to the file to save." + }) + }, + } + + RETURN_TYPES = ("STRING", ) + RETURN_NAMES = ("text to control order", ) + FUNCTION = "save_images" + + OUTPUT_NODE = True + + CATEGORY = "image" + DESCRIPTION = "Saves the input images to an absolute path." + + def save_images(self, images, absolute_filename): + i = 255.0 * images[0].cpu().numpy() + img = Image.fromarray(np.clip(i, 0, 255).astype(np.uint8)) + img.save(absolute_filename) + + return (absolute_filename, ) + + +class SaveText_absolute: + + def __init__(self): + pass + + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "text": ("STRING", { + "multiline": True, + "dynamicPrompts": True, + "tooltip": "Text to be saved to the file." + }), + "absolute_filename": ("STRING", { + "default": + "image.txt", + "tooltip": + "The absolute path to the file to save." + }) + }, + "optional": { + "text_opt": ("STRING", { + "multiline": + True, + "dynamicPrompts": + True, + "tooltip": + "Text to provide order when necessary (to create work files after txt files)." + }), + } + } + + RETURN_TYPES = ("STRING", ) + RETURN_NAMES = ("same text as input", ) + FUNCTION = "save_text" + + OUTPUT_NODE = True + + CATEGORY = "text" + DESCRIPTION = "Saves the input text to an absolute path." + + def save_text(self, text, absolute_filename, text_opt=''): + open(absolute_filename, "w").write(text) + return (text, ) + + +class Wait_And_Read_File: + + def __init__(self): + pass + + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "absolute_filename": ("STRING", { + "default": + "image.txt", + "tooltip": + "The absolute path to the file to read." + }) + }, + "optional": { + "text": ("STRING", { + "multiline": + True, + "dynamicPrompts": + True, + "tooltip": + "Text to provide order when necessary (to wait on done file)." + }), + } + } + + RETURN_TYPES = ("STRING", ) + RETURN_NAMES = ("text from file", ) + FUNCTION = "read_text" + + OUTPUT_NODE = True + + CATEGORY = "text" + DESCRIPTION = "Saves the input text to an absolute path." + + def read_text(self, absolute_filename, text=''): + while not os.path.exists(absolute_filename): + time.sleep(0.1) + + res = open(absolute_filename, "r").read() + os.unlink(absolute_filename) + + return (res, )