mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2025-04-20 03:13:30 +00:00
add SaveImageWEBP node
This pull request introduces a new node, `SaveImageWEBP`, which allows users to save images in the WebP format. As WebP images are typically 25-35% smaller than PNGs with comparable quality. This node: - Works exactly like the `SaveImage` node, but saves in WebP instead of PNG. - Lets users choose between lossless and lossy compression, adjust quality levels, and select encoding methods (`default`, `fastest`, or `slowest`). - Supports embedding metadata (e.g., prompts and additional info) into the WebP files using Exif tags, and is compatible with ComfyUI's existing metadata system. Metadata handling uses Exif tags, just like the `SaveAnimatedWEBP` node.
This commit is contained in:
parent
60653004e5
commit
4f989510b4
75
nodes.py
75
nodes.py
@ -1627,6 +1627,79 @@ class SaveImage:
|
||||
|
||||
return { "ui": { "images": results } }
|
||||
|
||||
class SaveImageWEBP:
|
||||
def __init__(self):
|
||||
self.output_dir = folder_paths.get_output_directory()
|
||||
self.type = "output"
|
||||
self.prefix_append = ""
|
||||
|
||||
methods = {"default": 4, "fastest": 0, "slowest": 6}
|
||||
|
||||
@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."}),
|
||||
"lossless": ("BOOLEAN", {"default": True}),
|
||||
"quality": ("INT", {"default": 80, "min": 0, "max": 100}),
|
||||
"method": (list(s.methods.keys()), {"default": "default"}),
|
||||
},
|
||||
"hidden": {
|
||||
"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO"
|
||||
},
|
||||
}
|
||||
|
||||
RETURN_TYPES = ()
|
||||
FUNCTION = "save_images"
|
||||
|
||||
OUTPUT_NODE = True
|
||||
|
||||
CATEGORY = "image"
|
||||
|
||||
def save_images(self, images, filename_prefix, lossless, quality, method, 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 = []
|
||||
method = self.methods.get(method, 4)
|
||||
|
||||
for (batch_number, image) in enumerate(images):
|
||||
# Convert tensor to PIL image
|
||||
i = 255. * image.cpu().numpy()
|
||||
img = Image.fromarray(np.clip(i, 0, 255).astype(np.uint8))
|
||||
|
||||
metadata = None
|
||||
if not args.disable_metadata:
|
||||
# Create Exif metadata
|
||||
exif_data = img.getexif()
|
||||
if prompt is not None:
|
||||
exif_data[0x0110] = "prompt:{}".format(json.dumps(prompt))
|
||||
if extra_pnginfo is not None:
|
||||
initial_exif = 0x010f # Starting tag for custom metadata
|
||||
for key in extra_pnginfo:
|
||||
exif_data[initial_exif] = "{}:{}".format(key, json.dumps(extra_pnginfo[key]))
|
||||
initial_exif -= 1 # Use lower tags for additional data
|
||||
metadata = exif_data
|
||||
|
||||
# Construct filename
|
||||
filename_with_batch = filename.replace("%batch_num%", str(batch_number))
|
||||
file = f"{filename_with_batch}_{counter:05}_.webp"
|
||||
img.save(
|
||||
os.path.join(full_output_folder, file),
|
||||
exif=metadata,
|
||||
lossless=lossless,
|
||||
quality=quality,
|
||||
method=method
|
||||
)
|
||||
results.append({
|
||||
"filename": file,
|
||||
"subfolder": subfolder,
|
||||
"type": self.type
|
||||
})
|
||||
counter += 1
|
||||
|
||||
return {"ui": {"images": results}}
|
||||
|
||||
class PreviewImage(SaveImage):
|
||||
def __init__(self):
|
||||
self.output_dir = folder_paths.get_temp_directory()
|
||||
@ -1945,6 +2018,7 @@ NODE_CLASS_MAPPINGS = {
|
||||
"LatentFromBatch": LatentFromBatch,
|
||||
"RepeatLatentBatch": RepeatLatentBatch,
|
||||
"SaveImage": SaveImage,
|
||||
"SaveImageWEBP": SaveImageWEBP,
|
||||
"PreviewImage": PreviewImage,
|
||||
"LoadImage": LoadImage,
|
||||
"LoadImageMask": LoadImageMask,
|
||||
@ -2045,6 +2119,7 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"RepeatLatentBatch": "Repeat Latent Batch",
|
||||
# Image
|
||||
"SaveImage": "Save Image",
|
||||
"SaveImageWEBP": "Save Image (WEBP)",
|
||||
"PreviewImage": "Preview Image",
|
||||
"LoadImage": "Load Image",
|
||||
"LoadImageMask": "Load Image (as Mask)",
|
||||
|
Loading…
Reference in New Issue
Block a user