-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSave_as_jpeg.py
103 lines (84 loc) · 3.84 KB
/
Save_as_jpeg.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import numpy as np
from PIL import Image
import folder_paths
import os
import json
# by Kaharos94
# https://github.com/Kaharos94/ComfyUI-Saveasjpeg
# comfyUI node to save an image in jpeg format
class Save_as_jpeg:
def __init__(self):
self.output_dir = folder_paths.get_output_directory()
self.type = "output"
@classmethod
def INPUT_TYPES(s):
return {"required":
{"images": ("IMAGE", ),
"filename_prefix": ("STRING", {"default": "ComfyUI"}),
"savePrompt":(["yes","no"],),
"compression":("INT", {"default": 80, "min": 1, "max": 100, "step": 1},)},
"hidden": {"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO", "mode":"lossy" },
}
RETURN_TYPES = ()
FUNCTION = "Save_as_jpeg"
OUTPUT_NODE = True
CATEGORY = "image"
def Save_as_jpeg(self, savePrompt, compression, images, filename_prefix="ComfyUI", prompt=None, extra_pnginfo=None , mode="lossy"):
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):
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()
for image in images:
i = 255. * image.cpu().numpy()
img = Image.fromarray(np.clip(i, 0, 255).astype(np.uint8))
workflowmetadata = str()
promptstr = str()
imgexif = img.getexif() #get the (empty) Exif data of the generated Picture
if prompt is not None:
promptstr="".join(json.dumps(prompt)) #prepare prompt String
if savePrompt == "yes":
imgexif[0x010f] ="Prompt:"+ promptstr #Add PromptString to EXIF position 0x010f (Exif.Image.Make)
if extra_pnginfo is not None:
for x in extra_pnginfo:
workflowmetadata += "".join(json.dumps(extra_pnginfo[x]))
if savePrompt == "yes":
imgexif[0x010e] = "Workflow:"+ workflowmetadata #Add Workflowstring to EXIF position 0x010e (Exif.Image.ImageDescription)
file = f"{filename}_{counter:05}_.jpeg"
if mode =="lossless":
boolloss = True
if mode =="lossy":
boolloss = False
img.save(os.path.join(full_output_folder, file), method=6 , exif= imgexif, lossless=boolloss , quality=compression) #Save as jpeg - options to be determined
results.append({
"filename": file,
"subfolder": subfolder,
"type": self.type
});
counter += 1
return { "ui": { "images": results } }
NODE_CLASS_MAPPINGS = {
"Save_as_jpeg": Save_as_jpeg
}