From cda23df1aba1afba4fe1fe109cc8ab74a38c255e Mon Sep 17 00:00:00 2001 From: leestuartx Date: Mon, 22 Jul 2024 07:36:34 -0600 Subject: [PATCH] Update Readme, fix metadata extractor --- README.md | 5 +- img/extract_by_seed.jpg | Bin 0 -> 18359 bytes img/image_metadata.jpg | Bin 0 -> 24542 bytes nodes/image_metadata_extractor.py | 145 +++--------------------------- nodes/metadata_extract_by_seed.py | 4 + 5 files changed, 18 insertions(+), 136 deletions(-) create mode 100644 img/extract_by_seed.jpg create mode 100644 img/image_metadata.jpg diff --git a/README.md b/README.md index 6e169be..ac5bd92 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,6 @@ ComfyUI-GG is a collection of ComfyUI nodes designed to enhance productivity in ## Nodes ### 1. Add Padding to Image - **Description:** This node adds pixel padding to the image to achieve a specified dimension. @@ -46,6 +45,8 @@ This node resizes an image proportionally based on a user-defined width. **Description:** This node loads an image and extracts its metadata, which can be used for additional image processing. +Node Padding + **Usage:** - Input an image. - The node will extract and output the metadata from the image. @@ -56,6 +57,8 @@ This node loads an image and extracts its metadata, which can be used for additi **Description:** This node iterates through images in a directory using a seed, loads each image, and extracts its metadata. This metadata can be used for upscale/resampling automation. +Node Padding + **Usage:** - Input a seed value. - Provide the directory containing the images. diff --git a/img/extract_by_seed.jpg b/img/extract_by_seed.jpg new file mode 100644 index 0000000000000000000000000000000000000000..260ff7952f427e50751ea144613aaf7429a69f9a GIT binary patch literal 18359 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 V2D@JYURXH~EvW)5opS%}{{z%3u*(1d literal 0 HcmV?d00001 diff --git a/img/image_metadata.jpg b/img/image_metadata.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c88943232e5b46f373277ddcd606ecb1d5f28d16 GIT binary patch literal 24542 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 AH2?qr literal 0 HcmV?d00001 diff --git a/nodes/image_metadata_extractor.py b/nodes/image_metadata_extractor.py index f9bcfe9..895f536 100644 --- a/nodes/image_metadata_extractor.py +++ b/nodes/image_metadata_extractor.py @@ -5,6 +5,7 @@ import numpy as np from sd_parsers import ParserManager, PromptInfo import folder_paths from typing import Any, Dict, List +from common.metadata_parser import MetadataParser # Initialize the parser manager parser_manager = ParserManager() @@ -53,71 +54,19 @@ class ImageMetadataExtractor: width, height = img.size filename = os.path.basename(image_path) - metadata = '' - raw_metadata = '' - cfg_scale = 0 - steps = 0 + parser = MetadataParser() + prompt_info, formatted_metadata, cfg_scale, steps, width, height, positive_prompt, negative_prompt, clip_skip, vaes, models, sampler_name, scheduler, denoise = parser.extract_metadata(image_path) - positive_prompt = '' - negative_prompt = '' - clip_skip = 0 - model_name = '' - - # Parse the image directly using the parser manager - prompt_info = None + model_name = ', '.join(models) try: prompt_info = parser_manager.parse(img) - print(prompt_info) - - if prompt_info: - print('There is metadata') - try: - metadata = self.format_metadata(prompt_info) - except: - print('cant parse metadata') - - try: - raw_metadata = self.format_raw_metadata(prompt_info) - except: - print('cant parse raw metadata') - - try: - cfg_scale = self.get_float(prompt_info.parameters, 'cfg') - except: - print('cant parse cfg scale') - - try: - steps = self.get_int(prompt_info.parameters, 'steps') - except: - pass - try: - positive_prompt = self.get_prompt_text(prompt_info.prompts) - except: - print('cant parse positive prompt') - try: - negative_prompt = self.get_prompt_text(prompt_info.negative_prompts) - except: - pass - - try: - clip_skip = self.get_int(prompt_info.parameters, 'clip') - except: - pass - try: - model_name = '' # self.get_model_name(prompt_info) - except: - pass - except: - print('could not parse default metadata') - - # Try extracting the positive prompt using the new method - temp_metadata = self.extract_metadata_type2(image_path) - metadata_str_keys = self.convert_keys_to_strings(temp_metadata) - if metadata_str_keys: - prompt_data = self.find_positive_prompt_data(metadata_str_keys) - if len(prompt_data) > 0: - positive_prompt = prompt_data[0] + metadata = self.format_metadata(prompt_info) + raw_metadata = str(prompt_info) + except Exception as e: + print('Error extracting metadata:', e) + metadata = '' + raw_metadata = '' return ( output_image, output_mask, metadata, cfg_scale, steps, int(width), int(height), @@ -125,72 +74,6 @@ class ImageMetadataExtractor: filename, raw_metadata ) - - def extract_metadata_type2(self, file_path: str) -> Dict[str, Any]: - try: - img = Image.open(file_path) - # Extract metadata using sd_parsers - prompt_info = parser_manager.parse(file_path) - if not prompt_info: - raise ValueError("No metadata found in image.") - metadata = { - "prompt": prompt_info.parameters, - "workflow": prompt_info.metadata - } - return metadata - except Exception as e: - raise ValueError(f"Error extracting metadata: {e}") - - def convert_keys_to_strings(self, d): - if isinstance(d, dict): - return {str(k): self.convert_keys_to_strings(v) for k, v in d.items()} - elif isinstance(d, list): - return [self.convert_keys_to_strings(i) for i in d] - else: - return d - - def find_positive_prompt_data(self, metadata: Dict[str, Any]) -> List[str]: - output_data = [] - - # Checking in both 'prompt' and 'workflow' sections for relevant nodes - for key, section in metadata.items(): - if key == 'workflow' and isinstance(section, dict): - if "nodes" in section: - for node in section["nodes"]: - if node.get("type") == "ShowText|pysssss" and node.get("properties", {}).get("Node name for S&R") == "ShowText|pysssss": - widgets_values = node.get("widgets_values", []) - for widget in widgets_values: - if isinstance(widget, list): - text_value = widget[0] - output_data.append(text_value) - else: - for subkey, subsection in section.items(): - if subkey == 'workflow' and isinstance(subsection, dict): - print(subsection) - if "nodes" in subsection: - print('found nodes') - for node in subsection["nodes"]: - if node.get("type") == "ShowText|pysssss" and node.get("properties", {}).get("Node name for S&R") == "ShowText|pysssss": - widgets_values = node.get("widgets_values", []) - for widget in widgets_values: - if isinstance(widget, list): - text_value = widget[0] - output_data.append(text_value) - - elif isinstance(section, dict): - for subkey, subsection in section.items(): - if subkey == 'workflow' and isinstance(subsection, dict): - if "nodes" in subsection: - for node in subsection["nodes"]: - if node.get("type") == "ShowText|pysssss" and node.get("properties", {}).get("Node name for S&R") == "ShowText|pysssss": - widgets_values = node.get("widgets_values", []) - for widget in widgets_values: - if isinstance(widget, list): - text_value = widget[0] - output_data.append(text_value) - - return output_data - def format_metadata(self, prompt_info): metadata_parts = [] @@ -229,9 +112,6 @@ class ImageMetadataExtractor: return '\n\n'.join(metadata_parts) - def format_raw_metadata(self, prompt_info): - return str(prompt_info) - def get_float(self, parameters, key): try: value = str(parameters.get(key, '0.0')).strip() @@ -246,11 +126,6 @@ class ImageMetadataExtractor: except (ValueError, TypeError): return 0 - def get_prompt_text(self, prompts): - if prompts: - return '\n'.join([prompt.value for prompt in prompts]) - return "" - NODE_CLASS_MAPPINGS = { "ImageMetadataExtractor": ImageMetadataExtractor diff --git a/nodes/metadata_extract_by_seed.py b/nodes/metadata_extract_by_seed.py index 306c60a..1b53c98 100644 --- a/nodes/metadata_extract_by_seed.py +++ b/nodes/metadata_extract_by_seed.py @@ -61,6 +61,9 @@ class MetadataExtractorBySeed: width, height = img.size filename = os.path.basename(image_path) + + ''' + # Parse the image directly using the parser manager prompt_info = parser_manager.parse(img) if prompt_info: @@ -91,6 +94,7 @@ class MetadataExtractorBySeed: "", "", 0, "Unknown", os.path.basename(image_path), "" ) + ''' except Exception as e: logging.exception("Error processing image") return (