LoadLatent and SaveLatent should behave like the LoadImage and SaveImage.
This commit is contained in:
parent
a7375103b9
commit
faf899ad5a
|
@ -147,4 +147,37 @@ def get_filename_list(folder_name):
|
||||||
output_list.update(filter_files_extensions(recursive_search(x), folders[1]))
|
output_list.update(filter_files_extensions(recursive_search(x), folders[1]))
|
||||||
return sorted(list(output_list))
|
return sorted(list(output_list))
|
||||||
|
|
||||||
|
def get_save_image_path(filename_prefix, output_dir, image_width=0, image_height=0):
|
||||||
|
def map_filename(filename):
|
||||||
|
prefix_len = len(os.path.basename(filename_prefix))
|
||||||
|
prefix = filename[:prefix_len + 1]
|
||||||
|
try:
|
||||||
|
digits = int(filename[prefix_len + 1:].split('_')[0])
|
||||||
|
except:
|
||||||
|
digits = 0
|
||||||
|
return (digits, prefix)
|
||||||
|
|
||||||
|
def compute_vars(input, image_width, image_height):
|
||||||
|
input = input.replace("%width%", str(image_width))
|
||||||
|
input = input.replace("%height%", str(image_height))
|
||||||
|
return input
|
||||||
|
|
||||||
|
filename_prefix = compute_vars(filename_prefix, image_width, image_height)
|
||||||
|
|
||||||
|
subfolder = os.path.dirname(os.path.normpath(filename_prefix))
|
||||||
|
filename = os.path.basename(os.path.normpath(filename_prefix))
|
||||||
|
|
||||||
|
full_output_folder = os.path.join(output_dir, subfolder)
|
||||||
|
|
||||||
|
if os.path.commonpath((output_dir, os.path.abspath(full_output_folder))) != output_dir:
|
||||||
|
print("Saving image outside the output folder is not allowed.")
|
||||||
|
return {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
counter = max(filter(lambda a: a[1][:-1] == filename and a[1][-1] == "_", map(map_filename, os.listdir(full_output_folder))))[0] + 1
|
||||||
|
except ValueError:
|
||||||
|
counter = 1
|
||||||
|
except FileNotFoundError:
|
||||||
|
os.makedirs(full_output_folder, exist_ok=True)
|
||||||
|
counter = 1
|
||||||
|
return full_output_folder, filename, counter, subfolder, filename_prefix
|
||||||
|
|
90
nodes.py
90
nodes.py
|
@ -251,13 +251,12 @@ class VAEEncodeForInpaint:
|
||||||
|
|
||||||
class SaveLatent:
|
class SaveLatent:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.output_dir = os.path.join(folder_paths.get_input_directory(), "latents")
|
self.output_dir = folder_paths.get_output_directory()
|
||||||
self.type = "output"
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def INPUT_TYPES(s):
|
||||||
return {"required": { "samples": ("LATENT", ),
|
return {"required": { "samples": ("LATENT", ),
|
||||||
"filename_prefix": ("STRING", {"default": "ComfyUI"})},
|
"filename_prefix": ("STRING", {"default": "latents/ComfyUI"})},
|
||||||
"hidden": {"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO"},
|
"hidden": {"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO"},
|
||||||
}
|
}
|
||||||
RETURN_TYPES = ()
|
RETURN_TYPES = ()
|
||||||
|
@ -268,31 +267,7 @@ class SaveLatent:
|
||||||
CATEGORY = "_for_testing"
|
CATEGORY = "_for_testing"
|
||||||
|
|
||||||
def save(self, samples, filename_prefix="ComfyUI", prompt=None, extra_pnginfo=None):
|
def save(self, samples, filename_prefix="ComfyUI", prompt=None, extra_pnginfo=None):
|
||||||
def map_filename(filename):
|
full_output_folder, filename, counter, subfolder, filename_prefix = folder_paths.get_save_image_path(filename_prefix, self.output_dir)
|
||||||
prefix_len = len(os.path.basename(filename_prefix))
|
|
||||||
prefix = filename[:prefix_len + 1]
|
|
||||||
try:
|
|
||||||
digits = int(filename[prefix_len + 1:].split('_')[0])
|
|
||||||
except:
|
|
||||||
digits = 0
|
|
||||||
return (digits, prefix)
|
|
||||||
|
|
||||||
subfolder = os.path.dirname(os.path.normpath(filename_prefix))
|
|
||||||
filename = os.path.basename(os.path.normpath(filename_prefix))
|
|
||||||
|
|
||||||
full_output_folder = os.path.join(self.output_dir, subfolder)
|
|
||||||
|
|
||||||
if os.path.commonpath((self.output_dir, os.path.abspath(full_output_folder))) != self.output_dir:
|
|
||||||
print("Saving latent outside the 'input/latents' folder is not allowed.")
|
|
||||||
return {}
|
|
||||||
|
|
||||||
try:
|
|
||||||
counter = max(filter(lambda a: a[1][:-1] == filename and a[1][-1] == "_", map(map_filename, os.listdir(full_output_folder))))[0] + 1
|
|
||||||
except ValueError:
|
|
||||||
counter = 1
|
|
||||||
except FileNotFoundError:
|
|
||||||
os.makedirs(full_output_folder, exist_ok=True)
|
|
||||||
counter = 1
|
|
||||||
|
|
||||||
# support save metadata for latent sharing
|
# support save metadata for latent sharing
|
||||||
prompt_info = ""
|
prompt_info = ""
|
||||||
|
@ -316,11 +291,10 @@ class SaveLatent:
|
||||||
|
|
||||||
|
|
||||||
class LoadLatent:
|
class LoadLatent:
|
||||||
input_dir = os.path.join(folder_paths.get_input_directory(), "latents")
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def INPUT_TYPES(s):
|
||||||
files = [f for f in os.listdir(s.input_dir) if os.path.isfile(os.path.join(s.input_dir, f)) and f.endswith(".latent")]
|
input_dir = folder_paths.get_input_directory()
|
||||||
|
files = [f for f in os.listdir(input_dir) if os.path.isfile(os.path.join(input_dir, f)) and f.endswith(".latent")]
|
||||||
return {"required": {"latent": [sorted(files), ]}, }
|
return {"required": {"latent": [sorted(files), ]}, }
|
||||||
|
|
||||||
CATEGORY = "_for_testing"
|
CATEGORY = "_for_testing"
|
||||||
|
@ -329,13 +303,25 @@ class LoadLatent:
|
||||||
FUNCTION = "load"
|
FUNCTION = "load"
|
||||||
|
|
||||||
def load(self, latent):
|
def load(self, latent):
|
||||||
file = folder_paths.get_annotated_filepath(latent, self.input_dir)
|
latent_path = folder_paths.get_annotated_filepath(latent)
|
||||||
|
latent = safetensors.torch.load_file(latent_path, device="cpu")
|
||||||
latent = safetensors.torch.load_file(file, device="cpu")
|
|
||||||
samples = {"samples": latent["latent_tensor"]}
|
samples = {"samples": latent["latent_tensor"]}
|
||||||
|
|
||||||
return (samples, )
|
return (samples, )
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def IS_CHANGED(s, latent):
|
||||||
|
image_path = folder_paths.get_annotated_filepath(latent)
|
||||||
|
m = hashlib.sha256()
|
||||||
|
with open(image_path, 'rb') as f:
|
||||||
|
m.update(f.read())
|
||||||
|
return m.digest().hex()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def VALIDATE_INPUTS(s, latent):
|
||||||
|
if not folder_paths.exists_annotated_filepath(latent):
|
||||||
|
return "Invalid latent file: {}".format(latent)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class CheckpointLoader:
|
class CheckpointLoader:
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -1020,39 +1006,7 @@ class SaveImage:
|
||||||
CATEGORY = "image"
|
CATEGORY = "image"
|
||||||
|
|
||||||
def save_images(self, images, filename_prefix="ComfyUI", prompt=None, extra_pnginfo=None):
|
def save_images(self, images, filename_prefix="ComfyUI", prompt=None, extra_pnginfo=None):
|
||||||
def map_filename(filename):
|
full_output_folder, filename, counter, subfolder, filename_prefix = folder_paths.get_save_image_path(filename_prefix, self.output_dir, images[0].shape[1], images[0].shape[0])
|
||||||
prefix_len = len(os.path.basename(filename_prefix))
|
|
||||||
prefix = filename[:prefix_len + 1]
|
|
||||||
try:
|
|
||||||
digits = int(filename[prefix_len + 1:].split('_')[0])
|
|
||||||
except:
|
|
||||||
digits = 0
|
|
||||||
return (digits, prefix)
|
|
||||||
|
|
||||||
def compute_vars(input):
|
|
||||||
input = input.replace("%width%", str(images[0].shape[1]))
|
|
||||||
input = input.replace("%height%", str(images[0].shape[0]))
|
|
||||||
return input
|
|
||||||
|
|
||||||
filename_prefix = compute_vars(filename_prefix)
|
|
||||||
|
|
||||||
subfolder = os.path.dirname(os.path.normpath(filename_prefix))
|
|
||||||
filename = os.path.basename(os.path.normpath(filename_prefix))
|
|
||||||
|
|
||||||
full_output_folder = os.path.join(self.output_dir, subfolder)
|
|
||||||
|
|
||||||
if os.path.commonpath((self.output_dir, os.path.abspath(full_output_folder))) != self.output_dir:
|
|
||||||
print("Saving image outside the output folder is not allowed.")
|
|
||||||
return {}
|
|
||||||
|
|
||||||
try:
|
|
||||||
counter = max(filter(lambda a: a[1][:-1] == filename and a[1][-1] == "_", map(map_filename, os.listdir(full_output_folder))))[0] + 1
|
|
||||||
except ValueError:
|
|
||||||
counter = 1
|
|
||||||
except FileNotFoundError:
|
|
||||||
os.makedirs(full_output_folder, exist_ok=True)
|
|
||||||
counter = 1
|
|
||||||
|
|
||||||
results = list()
|
results = list()
|
||||||
for image in images:
|
for image in images:
|
||||||
i = 255. * image.cpu().numpy()
|
i = 255. * image.cpu().numpy()
|
||||||
|
|
Loading…
Reference in New Issue