diff --git a/__init__.py b/__init__.py index 9e1f1ab..96ddd42 100644 --- a/__init__.py +++ b/__init__.py @@ -3,19 +3,22 @@ from .nodes.LoadLoraFromCivitAI import LoadLoraFromCivitAIWithDownloader from .nodes.LoadLoraFromHF import LoadLoraFromHFWithDownloader from .nodes.LoadHunyuanLoraFromCivitAI import LoadHunyuanLoraFromCivitAIWithDownloader from .nodes.upload_anything import UploadAnything +from .nodes.save_file import ComfyOnlineSaveFile NODE_CLASS_MAPPINGS = { "LoadLoraFromCivitAI":LoadLoraFromCivitAIWithDownloader, "LoadHunyuanLoraFromCivitAI":LoadHunyuanLoraFromCivitAIWithDownloader, "LoadLoraFromHF":LoadLoraFromHFWithDownloader, "ComfyOnlineUploadAnything": UploadAnything, + "ComfyOnlineSaveFile": ComfyOnlineSaveFile } NODE_DISPLAY_NAME_MAPPINGS = { "LoadLoraFromCivitAI" : "Load Lora From CivitAI", "LoadLoraFromHF" : "Load Lora From HuggingFace", "LoadHunyuanLoraFromCivitAI": "Load HunyuanLora From CivitAI", - 'ComfyOnlineUploadAnything': "ComfyOnlineUploadAnything" + 'ComfyOnlineUploadAnything': "ComfyOnlineUploadAnything", + "ComfyOnlineSaveFile": "ComfyOnlineSaveFile" } WEB_DIRECTORY = "./web" diff --git a/nodes/save_file.py b/nodes/save_file.py new file mode 100644 index 0000000..0239a2b --- /dev/null +++ b/nodes/save_file.py @@ -0,0 +1,96 @@ +import hashlib +import os + +import folder_paths + +class ComfyOnlineSaveFile: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "file_path": ("STRING", {"tooltip": "filename"}) + }, + } + + CATEGORY = "comfyonline-dynamic" + OUTPUT_NODE = True + + + RETURN_TYPES = () + FUNCTION = "save" + + def save(self, file_path): + file_path = os.path.abspath(file_path) + output_dir = folder_paths.get_output_directory() + output_dir = os.path.abspath(output_dir) + print(f"file_path is {file_path}, output_dir is {output_dir}") + # 判断路径是否在输出目录中 + if file_path.startswith(output_dir): + # 仅返回文件名 + filename = os.path.basename(file_path) + else: + filename = None # 如果不在目录中,返回 None 或者提示无效路径 + + results = list() + results.append({ + "filename": filename, + "subfolder": "", + "type": "output" + }) + return { "ui": { "file": results } } + + +class SaveImage: + def __init__(self): + self.output_dir = folder_paths.get_output_directory() + self.type = "output" + self.prefix_append = "" + self.compress_level = 4 + + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "images": ("IMAGE", {"tooltip": "The images to save."}), + "filename_prefix": ("STRING", {"default": "ComfyUI", "tooltip": "The prefix for the file to save. This may include formatting information such as %date:yyyy-MM-dd% or %Empty Latent Image.width% to include values from nodes."}) + }, + "hidden": { + "prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO" + }, + } + + RETURN_TYPES = () + FUNCTION = "save_images" + + OUTPUT_NODE = True + + CATEGORY = "image" + DESCRIPTION = "Saves the input images to your ComfyUI output directory." + + def save_images(self, images, filename_prefix="ComfyUI", prompt=None, extra_pnginfo=None): + filename_prefix += self.prefix_append + 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]) + results = list() + for (batch_number, image) in enumerate(images): + i = 255. * image.cpu().numpy() + img = Image.fromarray(np.clip(i, 0, 255).astype(np.uint8)) + metadata = None + if not args.disable_metadata: + metadata = PngInfo() + if prompt is not None: + metadata.add_text("prompt", json.dumps(prompt)) + if extra_pnginfo is not None: + for x in extra_pnginfo: + metadata.add_text(x, json.dumps(extra_pnginfo[x])) + + filename_with_batch_num = filename.replace("%batch_num%", str(batch_number)) + file = f"{filename_with_batch_num}_{counter:05}_.png" + img.save(os.path.join(full_output_folder, file), pnginfo=metadata, compress_level=self.compress_level) + results.append({ + "filename": file, + "subfolder": subfolder, + "type": self.type + }) + counter += 1 + + return { "ui": { "images": results } } \ No newline at end of file diff --git a/web/uploadAnything.js b/web/uploadAnything.js index e6d010a..4353738 100644 --- a/web/uploadAnything.js +++ b/web/uploadAnything.js @@ -20,7 +20,7 @@ async function uploadFile(file) { }); if (resp.status === 200) { - return resp.status + return resp } else { alert(resp.status + " - " + resp.statusText); } @@ -45,17 +45,17 @@ function addUploadWidget(nodeType, nodeData, widgetName) { style: "display: none", onchange: async () => { if (fileInput.files.length) { - if (await uploadFile(fileInput.files[0]) != 200) { + let resp = await uploadFile(fileInput.files[0]) + if (resp.status != 200) { //upload failed and file can not be added to options return; } - const filename = fileInput.files[0].name; + const filename = (await resp.json()).name; pathWidget.options.values.push(filename); pathWidget.value = filename; if (pathWidget.callback) { pathWidget.callback(filename) } - app.graph.setDirtyCanvas(true); } }, });