Add extra_metadata
This commit is contained in:
@@ -58,6 +58,10 @@ git clone https://github.com/nkchocoai/ComfyUI-SaveImageWithMetaData.git
|
||||
##### By node ID
|
||||
- ノードIDが `sampler_selection_node_id` であるKSamplerノードを選びます。
|
||||
|
||||
### Create Extra MetaData
|
||||
- 保存する画像に追加するメタデータを指定します。
|
||||
- 例: [extra_metadata.png](examples/extra_metadata.png)。
|
||||
|
||||
## 付与されるメタデータ
|
||||
- Positive prompt
|
||||
- Negative prompt
|
||||
|
||||
@@ -60,6 +60,10 @@ git clone https://github.com/nkchocoai/ComfyUI-SaveImageWithMetaData.git
|
||||
##### By node ID
|
||||
- Select the KSampler node whose node ID is `sampler_selection_node_id`.
|
||||
|
||||
### Create Extra MetaData
|
||||
- Specifies metadata to be added to the image to be saved.
|
||||
- Example: In [extra_metadata.png](examples/extra_metadata.png).
|
||||
|
||||
## Metadata to be given
|
||||
- Positive prompt
|
||||
- Negative prompt
|
||||
|
||||
+3
-1
@@ -1,11 +1,13 @@
|
||||
from .py.nodes.node import SaveImageWithMetaData
|
||||
from .py.nodes.node import SaveImageWithMetaData, CreateExtraMetaData
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"SaveImageWithMetaData": SaveImageWithMetaData,
|
||||
"CreateExtraMetaData": CreateExtraMetaData,
|
||||
}
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"SaveImageWithMetaData": "Save Image With Metadata",
|
||||
"CreateExtraMetaData": "Create Extra MetaData",
|
||||
}
|
||||
|
||||
__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"]
|
||||
|
||||
@@ -0,0 +1,667 @@
|
||||
{
|
||||
"last_node_id": 21,
|
||||
"last_link_id": 29,
|
||||
"nodes": [
|
||||
{
|
||||
"id": 10,
|
||||
"type": "VAEDecode",
|
||||
"pos": [
|
||||
812,
|
||||
429
|
||||
],
|
||||
"size": {
|
||||
"0": 210,
|
||||
"1": 46
|
||||
},
|
||||
"flags": {},
|
||||
"order": 9,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "samples",
|
||||
"type": "LATENT",
|
||||
"link": 9,
|
||||
"slot_index": 0
|
||||
},
|
||||
{
|
||||
"name": "vae",
|
||||
"type": "VAE",
|
||||
"link": 18
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "IMAGE",
|
||||
"type": "IMAGE",
|
||||
"links": [
|
||||
19
|
||||
],
|
||||
"shape": 3
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "VAEDecode"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"type": "CreateExtraMetaData",
|
||||
"pos": [
|
||||
763,
|
||||
962
|
||||
],
|
||||
"size": [
|
||||
245.1999969482422,
|
||||
226
|
||||
],
|
||||
"flags": {},
|
||||
"order": 8,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "extra_metadata",
|
||||
"type": "EXTRA_METADATA",
|
||||
"link": 20
|
||||
},
|
||||
{
|
||||
"name": "value1",
|
||||
"type": "STRING",
|
||||
"link": 27,
|
||||
"widget": {
|
||||
"name": "value1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "value2",
|
||||
"type": "STRING",
|
||||
"link": 26,
|
||||
"widget": {
|
||||
"name": "value2"
|
||||
}
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "EXTRA_METADATA",
|
||||
"type": "EXTRA_METADATA",
|
||||
"links": [
|
||||
25
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 0
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "CreateExtraMetaData"
|
||||
},
|
||||
"widgets_values": [
|
||||
"custom_w",
|
||||
"",
|
||||
"custom_h",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"type": "CreateExtraMetaData",
|
||||
"pos": [
|
||||
440,
|
||||
960
|
||||
],
|
||||
"size": {
|
||||
"0": 245.1999969482422,
|
||||
"1": 226
|
||||
},
|
||||
"flags": {},
|
||||
"order": 0,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "extra_metadata",
|
||||
"type": "EXTRA_METADATA",
|
||||
"link": null
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "EXTRA_METADATA",
|
||||
"type": "EXTRA_METADATA",
|
||||
"links": [
|
||||
20
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 0
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "CreateExtraMetaData"
|
||||
},
|
||||
"widgets_values": [
|
||||
"custom_key",
|
||||
"custom_value",
|
||||
"hello",
|
||||
"world",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"type": "CheckpointLoaderSimple",
|
||||
"pos": [
|
||||
-340,
|
||||
370
|
||||
],
|
||||
"size": {
|
||||
"0": 315,
|
||||
"1": 98
|
||||
},
|
||||
"flags": {},
|
||||
"order": 1,
|
||||
"mode": 0,
|
||||
"outputs": [
|
||||
{
|
||||
"name": "MODEL",
|
||||
"type": "MODEL",
|
||||
"links": [
|
||||
17
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 0
|
||||
},
|
||||
{
|
||||
"name": "CLIP",
|
||||
"type": "CLIP",
|
||||
"links": [
|
||||
13,
|
||||
14
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 1
|
||||
},
|
||||
{
|
||||
"name": "VAE",
|
||||
"type": "VAE",
|
||||
"links": [
|
||||
18
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 2
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "CheckpointLoaderSimple"
|
||||
},
|
||||
"widgets_values": [
|
||||
"animagine-xl-3.1.safetensors"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"type": "CLIPTextEncode",
|
||||
"pos": [
|
||||
40,
|
||||
600
|
||||
],
|
||||
"size": {
|
||||
"0": 315,
|
||||
"1": 98
|
||||
},
|
||||
"flags": {},
|
||||
"order": 4,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "clip",
|
||||
"type": "CLIP",
|
||||
"link": 14
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "CONDITIONING",
|
||||
"type": "CONDITIONING",
|
||||
"links": [
|
||||
15
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 0
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "CLIPTextEncode"
|
||||
},
|
||||
"widgets_values": [
|
||||
"lowres, (bad), text, error, fewer, extra, missing, worst quality, jpeg artifacts, low quality, watermark, unfinished, displeasing, oldest, early, chromatic aberration, signature, extra digits, artistic error, username, scan, [abstract]",
|
||||
true
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"type": "CLIPTextEncode",
|
||||
"pos": [
|
||||
40,
|
||||
430
|
||||
],
|
||||
"size": {
|
||||
"0": 315,
|
||||
"1": 98
|
||||
},
|
||||
"flags": {},
|
||||
"order": 3,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "clip",
|
||||
"type": "CLIP",
|
||||
"link": 13
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "CONDITIONING",
|
||||
"type": "CONDITIONING",
|
||||
"links": [
|
||||
16
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 0
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "CLIPTextEncode"
|
||||
},
|
||||
"widgets_values": [
|
||||
"1girl, hatsune miku, vocaloid, aqua hair, aqua eyes, twintails, aqua necktie, cyan shirt, sleeveless, detached sleeves, black sleeves, upper body, smile, looking at viewer, waving, masterpiece, best quality, very aesthetic, absurdres",
|
||||
true
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"type": "KSampler",
|
||||
"pos": [
|
||||
445,
|
||||
430
|
||||
],
|
||||
"size": {
|
||||
"0": 315,
|
||||
"1": 262
|
||||
},
|
||||
"flags": {},
|
||||
"order": 7,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "model",
|
||||
"type": "MODEL",
|
||||
"link": 17
|
||||
},
|
||||
{
|
||||
"name": "positive",
|
||||
"type": "CONDITIONING",
|
||||
"link": 16
|
||||
},
|
||||
{
|
||||
"name": "negative",
|
||||
"type": "CONDITIONING",
|
||||
"link": 15
|
||||
},
|
||||
{
|
||||
"name": "latent_image",
|
||||
"type": "LATENT",
|
||||
"link": 8,
|
||||
"slot_index": 3
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "LATENT",
|
||||
"type": "LATENT",
|
||||
"links": [
|
||||
9
|
||||
],
|
||||
"shape": 3
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "KSampler"
|
||||
},
|
||||
"widgets_values": [
|
||||
0,
|
||||
"fixed",
|
||||
20,
|
||||
8,
|
||||
"euler_ancestral",
|
||||
"karras",
|
||||
1
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"type": "CR Integer To String",
|
||||
"pos": [
|
||||
457,
|
||||
743
|
||||
],
|
||||
"size": [
|
||||
210,
|
||||
54
|
||||
],
|
||||
"flags": {},
|
||||
"order": 5,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "int_",
|
||||
"type": "INT",
|
||||
"link": 29,
|
||||
"widget": {
|
||||
"name": "int_"
|
||||
}
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "STRING",
|
||||
"type": "STRING",
|
||||
"links": [
|
||||
27
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 0
|
||||
},
|
||||
{
|
||||
"name": "show_help",
|
||||
"type": "STRING",
|
||||
"links": null,
|
||||
"shape": 3
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "CR Integer To String"
|
||||
},
|
||||
"widgets_values": [
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"type": "CR Integer To String",
|
||||
"pos": [
|
||||
460,
|
||||
847
|
||||
],
|
||||
"size": [
|
||||
210,
|
||||
54
|
||||
],
|
||||
"flags": {},
|
||||
"order": 6,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "int_",
|
||||
"type": "INT",
|
||||
"link": 28,
|
||||
"widget": {
|
||||
"name": "int_"
|
||||
}
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "STRING",
|
||||
"type": "STRING",
|
||||
"links": [
|
||||
26
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 0
|
||||
},
|
||||
{
|
||||
"name": "show_help",
|
||||
"type": "STRING",
|
||||
"links": null,
|
||||
"shape": 3
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "CR Integer To String"
|
||||
},
|
||||
"widgets_values": [
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"type": "EmptyLatentImageFromPresetsSDXL",
|
||||
"pos": [
|
||||
40,
|
||||
800
|
||||
],
|
||||
"size": {
|
||||
"0": 315,
|
||||
"1": 122
|
||||
},
|
||||
"flags": {},
|
||||
"order": 2,
|
||||
"mode": 0,
|
||||
"outputs": [
|
||||
{
|
||||
"name": "latent",
|
||||
"type": "LATENT",
|
||||
"links": [
|
||||
8
|
||||
],
|
||||
"shape": 3
|
||||
},
|
||||
{
|
||||
"name": "w",
|
||||
"type": "INT",
|
||||
"links": [
|
||||
29
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 1
|
||||
},
|
||||
{
|
||||
"name": "h",
|
||||
"type": "INT",
|
||||
"links": [
|
||||
28
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 2
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "EmptyLatentImageFromPresetsSDXL"
|
||||
},
|
||||
"widgets_values": [
|
||||
" 832 x 1216",
|
||||
1
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"type": "SaveImageWithMetaData",
|
||||
"pos": [
|
||||
1106,
|
||||
430
|
||||
],
|
||||
"size": [
|
||||
315,
|
||||
482
|
||||
],
|
||||
"flags": {},
|
||||
"order": 10,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "images",
|
||||
"type": "IMAGE",
|
||||
"link": 19
|
||||
},
|
||||
{
|
||||
"name": "extra_metadata",
|
||||
"type": "EXTRA_METADATA",
|
||||
"link": 25
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "SaveImageWithMetaData"
|
||||
},
|
||||
"widgets_values": [
|
||||
"extra_metadata",
|
||||
"Farthest",
|
||||
0,
|
||||
"png",
|
||||
true,
|
||||
100,
|
||||
false,
|
||||
true,
|
||||
false
|
||||
]
|
||||
}
|
||||
],
|
||||
"links": [
|
||||
[
|
||||
8,
|
||||
8,
|
||||
0,
|
||||
9,
|
||||
3,
|
||||
"LATENT"
|
||||
],
|
||||
[
|
||||
9,
|
||||
9,
|
||||
0,
|
||||
10,
|
||||
0,
|
||||
"LATENT"
|
||||
],
|
||||
[
|
||||
13,
|
||||
1,
|
||||
1,
|
||||
14,
|
||||
0,
|
||||
"CLIP"
|
||||
],
|
||||
[
|
||||
14,
|
||||
1,
|
||||
1,
|
||||
13,
|
||||
0,
|
||||
"CLIP"
|
||||
],
|
||||
[
|
||||
15,
|
||||
13,
|
||||
0,
|
||||
9,
|
||||
2,
|
||||
"CONDITIONING"
|
||||
],
|
||||
[
|
||||
16,
|
||||
14,
|
||||
0,
|
||||
9,
|
||||
1,
|
||||
"CONDITIONING"
|
||||
],
|
||||
[
|
||||
17,
|
||||
1,
|
||||
0,
|
||||
9,
|
||||
0,
|
||||
"MODEL"
|
||||
],
|
||||
[
|
||||
18,
|
||||
1,
|
||||
2,
|
||||
10,
|
||||
1,
|
||||
"VAE"
|
||||
],
|
||||
[
|
||||
19,
|
||||
10,
|
||||
0,
|
||||
15,
|
||||
0,
|
||||
"IMAGE"
|
||||
],
|
||||
[
|
||||
20,
|
||||
17,
|
||||
0,
|
||||
16,
|
||||
0,
|
||||
"EXTRA_METADATA"
|
||||
],
|
||||
[
|
||||
25,
|
||||
16,
|
||||
0,
|
||||
15,
|
||||
1,
|
||||
"EXTRA_METADATA"
|
||||
],
|
||||
[
|
||||
26,
|
||||
21,
|
||||
0,
|
||||
16,
|
||||
2,
|
||||
"STRING"
|
||||
],
|
||||
[
|
||||
27,
|
||||
20,
|
||||
0,
|
||||
16,
|
||||
1,
|
||||
"STRING"
|
||||
],
|
||||
[
|
||||
28,
|
||||
8,
|
||||
2,
|
||||
21,
|
||||
0,
|
||||
"INT"
|
||||
],
|
||||
[
|
||||
29,
|
||||
8,
|
||||
1,
|
||||
20,
|
||||
0,
|
||||
"INT"
|
||||
]
|
||||
],
|
||||
"groups": [],
|
||||
"config": {},
|
||||
"extra": {
|
||||
"ds": {
|
||||
"scale": 0.7513148009015779,
|
||||
"offset": [
|
||||
653.6784224287038,
|
||||
-213.77225271772178
|
||||
]
|
||||
}
|
||||
},
|
||||
"version": 0.4
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 366 KiB |
+56
-3
@@ -51,7 +51,8 @@ class SaveImageWithMetaData(BaseNode):
|
||||
"quality": ("INT", {"default": 100, "min": 1, "max": 100}),
|
||||
"save_workflow_json": ("BOOLEAN", {"default": False}),
|
||||
"add_counter_to_filename": ("BOOLEAN", {"default": True}),
|
||||
"civitai_sampler": ("BOOLEAN", {"default": False})
|
||||
"civitai_sampler": ("BOOLEAN", {"default": False}),
|
||||
"extra_metadata": ("EXTRA_METADATA", {}),
|
||||
},
|
||||
"hidden": {"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO"},
|
||||
}
|
||||
@@ -74,13 +75,18 @@ class SaveImageWithMetaData(BaseNode):
|
||||
quality=100,
|
||||
save_workflow_json=False,
|
||||
add_counter_to_filename=True,
|
||||
civitai_sampler = False,
|
||||
civitai_sampler=False,
|
||||
extra_metadata={},
|
||||
prompt=None,
|
||||
extra_pnginfo=None,
|
||||
):
|
||||
pnginfo_dict_src = self.gen_pnginfo(
|
||||
sampler_selection_method, sampler_selection_node_id, civitai_sampler
|
||||
)
|
||||
for k, v in extra_metadata.items():
|
||||
if k and v:
|
||||
pnginfo_dict_src[k] = v.replace(",", "/")
|
||||
|
||||
results = list()
|
||||
for index, image in enumerate(images):
|
||||
i = 255.0 * image.cpu().numpy()
|
||||
@@ -162,7 +168,9 @@ class SaveImageWithMetaData(BaseNode):
|
||||
return {"ui": {"images": results}}
|
||||
|
||||
@classmethod
|
||||
def gen_pnginfo(cls, sampler_selection_method, sampler_selection_node_id, save_civitai_sampler):
|
||||
def gen_pnginfo(
|
||||
cls, sampler_selection_method, sampler_selection_node_id, save_civitai_sampler
|
||||
):
|
||||
# get all node inputs
|
||||
inputs = Capture.get_inputs()
|
||||
|
||||
@@ -246,3 +254,48 @@ class SaveImageWithMetaData(BaseNode):
|
||||
filename = filename.replace(segment, date_format)
|
||||
|
||||
return filename
|
||||
|
||||
|
||||
class CreateExtraMetaData(BaseNode):
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {
|
||||
"required": {
|
||||
"key1": ("STRING", {"default": "", "multiline": False}),
|
||||
"value1": ("STRING", {"default": "", "multiline": False}),
|
||||
},
|
||||
"optional": {
|
||||
"key2": ("STRING", {"default": "", "multiline": False}),
|
||||
"value2": ("STRING", {"default": "", "multiline": False}),
|
||||
"key3": ("STRING", {"default": "", "multiline": False}),
|
||||
"value3": ("STRING", {"default": "", "multiline": False}),
|
||||
"key4": ("STRING", {"default": "", "multiline": False}),
|
||||
"value4": ("STRING", {"default": "", "multiline": False}),
|
||||
"extra_metadata": ("EXTRA_METADATA",),
|
||||
},
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("EXTRA_METADATA",)
|
||||
FUNCTION = "create_extra_metadata"
|
||||
|
||||
def create_extra_metadata(
|
||||
self,
|
||||
extra_metadata={},
|
||||
key1="",
|
||||
value1="",
|
||||
key2="",
|
||||
value2="",
|
||||
key3="",
|
||||
value3="",
|
||||
key4="",
|
||||
value4="",
|
||||
):
|
||||
extra_metadata.update(
|
||||
{
|
||||
key1: value1,
|
||||
key2: value2,
|
||||
key3: value3,
|
||||
key4: value4,
|
||||
}
|
||||
)
|
||||
return (extra_metadata,)
|
||||
|
||||
Reference in New Issue
Block a user