This commit is contained in:
romeobuilderotti
2023-11-15 20:06:12 +03:00
commit 286a7579f8
6 changed files with 184 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
*.pyc
__pycache__
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 Romeo
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+34
View File
@@ -0,0 +1,34 @@
# ComfyUI-PNG-Metadata Custom Nodes
<img src="examples/workflow.png"/>
ComfyUI-PNG-Metadata is a set of custom nodes for ComfyUI. It provides nodes that allow to add custom metadata to your PNG files, such as the prompt and settings used to generate the image. This also can be used to add "parameters" metadata item compatible with AUTOMATIC1111 metadata.
To use the nodes, simply add them to your workflow and connect the inputs. This will automatically add the metadata to any standard "save image" nodes.
The nodes provided in this library are:
1. **Set Metadata** - Set a single custom metadata field and optionally update 'parameters' field in png metadata.
2. **Set Metadata (All)** - Set multiple metadata at once and write them to 'parameters' field in png metadata.
*Note*: Currently the node execution order is not enforced, so if Metadata nodes execute after the Save Image node, the metadata will not be written to the image. This will be fixed in a future release.
## Installation
### Using ComfyUI-Manager
1. Install [ComfyUI-Manager](https://github.com/ltdrdata/ComfyUI-Manager) if it isn't already.
2. Press Install Custom Nodes from the ComfyUI-Manager menu
3. Search for ComfyUI-PNG-Metadata
4. Click install
### Manual installation
Follow the steps below to install the ComfyUI-PNG-Metadata Library. These commands assume your current working directory is the ComfyUI root directory.
1. Clone the repository:
```
git clone https://github.com/romeobuilderotti/ComfyUI-PNG-Metadata custom_nodes/ComfyUI-PNG-Metadata
```
2. Restart your ComfyUI.
3. You can find example workflows in the `custom_nodes/ComfyUI-PNG-Metadata/examples` directory.
+14
View File
@@ -0,0 +1,14 @@
from .metadata import SetMetadataString, SetMetadataAll
NODE_CLASS_MAPPINGS = {
"SetMetadataString": SetMetadataString,
"SetMetadataAll": SetMetadataAll,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"SetMetadataString": "Set Metadata",
"SetMetadataAll": "Set Metadata (All)",
}
__version__ = "0.1.0"
__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"]
Binary file not shown.

After

Width:  |  Height:  |  Size: 308 KiB

+113
View File
@@ -0,0 +1,113 @@
import comfy
class SetMetadataString:
"""
Set a single custom metadata field and optionally update 'parameters' field in png metadata
"""
CATEGORY = "utils"
RETURN_TYPES = ()
OUTPUT_NODE = True
FUNCTION = "process"
SET_PARAMETERS = True
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"name": ("STRING", {}),
"value": ("STRING", {"forceInput": True, "default": ""}),
},
"hidden": {
"extra_pnginfo": "EXTRA_PNGINFO"
},
}
def process(self, name: str, value: str = "", update_parameters: bool = True, extra_pnginfo=None):
if extra_pnginfo is not None and name and value:
extra_pnginfo[name] = value
if self.SET_PARAMETERS and name != "parameters":
extra_pnginfo["parameters"] = self.update_parameters(extra_pnginfo.get("parameters", ""), name, value)
return (None,)
def update_parameters(self, params_string: str, name: str, value: str) -> str:
"""Modify the a1111 compatible (mostly) parameters string to include the new parameter
Parameters format:
<Prompt>
[Negative prompt: <Negative prompt>]
[Steps: <steps>, Seed: <seed>, ...]
"""
prompt, *other = params_string.split("\n") + [""] * 3
negative = None
params = None
for item in other:
if item:
if item.startswith("Negative prompt: "):
negative = item
else:
params = item
if name.lower() == "prompt":
prompt = value
elif name.lower() in ("negative prompt", "negative"):
negative = f"Negative prompt: {value}"
else:
if isinstance(value, str) and any(c in value for c in (',', '\n', '"')):
value = '"' + value.replace('"', '\\"') + '"'
if params:
params += f", {name}: {value}"
else:
params = f"{name}: {value}"
return "\n".join(filter(None, [prompt, negative, params]))
class SetMetadataAll(SetMetadataString):
"""
Set multiple metadata at once and write them to 'parameters' field in png metadata
"""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {},
"optional": {
"prompt": ("STRING", {"forceInput": True, "default": None}),
"negative": ("STRING", {"forceInput": True, "default": None}),
"model_name": ("STRING", {"forceInput": True, "default": None}),
"steps": ("INT", {"forceInput": True, "default": None}),
"cfg": ("FLOAT", {"forceInput": True, "default": None}),
"sampler_name": (comfy.samplers.KSampler.SAMPLERS, {"forceInput": True, "default": None}),
"scheduler": (comfy.samplers.KSampler.SCHEDULERS, {"forceInput": True, "default": None}),
"seed": ("INT", {"forceInput": True, "default": None}),
},
"hidden": {
"extra_pnginfo": "EXTRA_PNGINFO"
},
}
def process(self, **kwargs):
extra_pnginfo = kwargs.pop("extra_pnginfo", None)
if extra_pnginfo is not None:
params = extra_pnginfo.get("parameters", "")
for k, v in kwargs.items():
if v is not None:
params = self.update_parameters(params, self.convert_name(k), self.convert_value(v))
if params:
extra_pnginfo["parameters"] = params
return (None,)
def convert_name(self, name: str) -> str:
names_dict = {
"prompt": "Prompt",
"negative": "Negative prompt",
"model_name": "Model",
"steps": "Steps",
"seed": "Seed",
"cfg": "CFG scale",
"sampler_name": "Sampler",
"scheduler": "Scheduler",
}
return names_dict.get(name, name)
def convert_value(self, value):
return value