Files
EricRollei-AAA_Metadata_System/documentation/ReadMe Docs/MetadataSystemUsageGuide.md
T

14 KiB

Metadata System Usage Guide

This guide provides detailed instructions and examples for using the Metadata System for ComfyUI. It covers basic and advanced usage, as well as integration with ComfyUI nodes.

Table of Contents

Basic Usage

Initialization

Initialize the MetadataService to start working with the system:

from Metadata_system import MetadataService

# Basic initialization
service = MetadataService()

# With debug mode enabled for troubleshooting
service = MetadataService(debug=True)

# With human-readable text format
service = MetadataService(human_readable_text=True)

# Using as a context manager (ensures proper cleanup)
with MetadataService() as service:
    # Your code here
    pass

Writing Metadata

Write metadata to one or more storage formats:

# Create metadata dictionary
metadata = {
    'basic': {
        'title': 'Mountain Landscape',
        'description': 'AI generated mountain landscape',
        'keywords': ['mountains', 'landscape', 'nature', 'AI'],
        'rating': 4
    },
    'ai_info': {
        'generation': {
            'model': 'stable-diffusion-v1-5',
            'prompt': 'majestic mountains with snow caps',
            'negative_prompt': 'ugly, blurry',
            'sampler': 'euler_a',
            'steps': 30,
            'cfg_scale': 7.5,
            'seed': 1234567890
        }
    }
}

# Write to all supported formats
result = service.write_metadata('path/to/image.png', metadata)

# Write to specific formats
result = service.write_metadata('path/to/image.png', metadata, 
                              targets=['embedded', 'xmp'])

# Check results
for target, success in result.items():
    print(f"{target}: {'Succeeded' if success else 'Failed'}")

Reading Metadata

Read metadata from storage formats:

# Read from embedded metadata with fallback
metadata = service.read_metadata('path/to/image.png', source='embedded', fallback=True)

# Read from specific source without fallback
xmp_metadata = service.read_metadata('path/to/image.png', source='xmp', fallback=False)

# Access specific sections
if 'basic' in metadata:
    print(f"Title: {metadata['basic'].get('title', 'No title')}")
    
if 'ai_info' in metadata and 'generation' in metadata['ai_info']:
    gen = metadata['ai_info']['generation']
    print(f"Model: {gen.get('model')}")
    print(f"Prompt: {gen.get('prompt')}")

Merging Metadata

Merge new metadata with existing metadata:

# New metadata to merge
new_metadata = {
    'basic': {
        'keywords': ['new', 'tags', 'to', 'add']
    },
    'analysis': {
        'technical': {
            'blur': {
                'score': 0.92,
                'higher_better': True
            }
        }
    }
}

# Merge with existing metadata
result = service.merge_metadata('path/to/image.png', new_metadata)

# Merge and write to specific targets
result = service.merge_metadata('path/to/image.png', new_metadata, 
                               targets=['embedded', 'txt'])

Metadata Structure

The metadata is organized into sections for different types of information:

Basic Section

Contains essential image information:

basic = {
    'title': 'Image Title',                         # Image title
    'description': 'Detailed description',          # Description/caption
    'keywords': ['keyword1', 'keyword2'],           # Tags/keywords
    'rating': 4,                                    # Rating (1-5)
    'creator': 'Author Name',                       # Creator/author
    'rights': 'Copyright information',              # Copyright/license
    'create_date': '2025-03-15T12:34:56'            # Creation timestamp
}

Analysis Section

Contains analysis results from various tools:

analysis = {
    'technical': {
        'blur': {
            'score': 0.92,                          # Blur detection score
            'higher_better': True                   # Whether higher is better
        },
        'noise': {
            'score': 0.08,                          # Noise detection score
            'higher_better': False                  # Whether higher is better
        }
    },
    'aesthetic': {
        'composition': 7.8,                         # Composition score
        'color_harmony': 8.2,                       # Color harmony score
        'overall': 7.9                              # Overall aesthetic score
    },
    'pyiqa': {
        'niqe': {                                   # No-reference IQA model
            'score': 3.45,
            'higher_better': False,
            'range': [0, 25]
        },
        'musiq': {                                  # Multi-scale IQA model
            'score': 78.2,
            'higher_better': True,
            'range': [0, 100]
        }
    },
    'classification': {
        'style': 'photorealistic',                  # Detected style
        'content_type': 'landscape',                # Content type
        'has_text': False                           # Text detection result
    }
}

AI Info Section

Contains AI generation information:

ai_info = {
    'generation': {
        'model': 'stable-diffusion-v1-5',           # Base model
        'prompt': 'mountain landscape',             # Positive prompt
        'negative_prompt': 'ugly, blurry',          # Negative prompt
        'sampler': 'euler_a',                       # Sampler name
        'steps': 30,                                # Sampling steps
        'cfg_scale': 7.5,                           # CFG scale
        'seed': 1234567890,                         # Generation seed
        'width': 512,                               # Image width
        'height': 512,                              # Image height
        'loras': [                                  # LoRAs used
            {
                'name': 'example_lora',
                'strength': 0.8
            }
        ]
    },
    'workflow': {                                   # Full workflow data
        # ComfyUI workflow data (simplified for brevity)
        'nodes': { ... }
    }
}

Regions Section

Contains information about specific regions in the image:

regions = {
    'faces': [                                       # Detected faces
        {
            'type': 'Face',
            'name': 'Person 1',
            'area': {                                # Face coordinates
                'x': 0.2,                            # Normalized (0-1)
                'y': 0.3,
                'w': 0.1,
                'h': 0.15
            },
            'extensions': {                          # Extended face data
                'eiqa': {
                    'face_analysis': {
                        'gender': 'female',
                        'age': 28,
                        'emotion': 'happy'
                    }
                }
            }
        }
    ],
    'areas': [                                       # Other detected areas
        {
            'type': 'Object',
            'name': 'Mountain',
            'area': {
                'x': 0.1,
                'y': 0.2,
                'w': 0.8,
                'h': 0.5
            }
        }
    ],
    'summary': {                                     # Summary statistics
        'face_count': 1,
        'detector_type': 'deepface'
    }
}

ComfyUI Node Usage

Metadata Save Image Node

The eric_metadata_save_image node saves images with metadata:

  1. Connect your image output to the node's images input
  2. Connect workflow data (optional) to the workflow_data input
  3. Set basic parameters:
    • save_path: Directory to save images
    • filename_prefix: Prefix for generated filenames
    • filename_number_padding: Number of digits for sequential numbering
    • filename_number_start: Starting number for sequential filenames
  4. Metadata options:
    • title: Image title
    • description: Image description
    • keywords: Comma-separated keywords
    • save_metadata_to: Formats to save metadata (embedded,xmp,txt,db)
    • human_readable_text: Use human-readable text format

This node automatically captures workflow data, generation parameters, and technical image information.

Metadata Entry Node

The eric_metadata_entry node allows adding custom metadata:

  1. Connect to any workflow position
  2. Fill in metadata fields:
    • Basic information (title, description, keywords)
    • Analysis scores
    • Custom fields
  3. Connect to other nodes that process metadata

Metadata Query Node

The eric_metadata_query_node filters and retrieves metadata:

  1. Connect to image input
  2. Set query parameters:
    • query_type: Type of query to perform
    • field_path: Path to the metadata field to query
    • comparison: Comparison operator (equals, greater_than, etc.)
    • value: Value to compare against
  3. Use outputs:
    • result: Query result
    • metadata: Full metadata dictionary
    • image: Passed-through image

Workflow Extractor Node

The eric_workflow_extractor node extracts workflow data from images:

  1. Connect to image input
  2. Set extraction parameters:
    • extraction_mode: How to extract workflow data
    • include_basic_metadata: Whether to include basic metadata
  3. Use outputs:
    • workflow_data: Extracted workflow JSON
    • metadata: Full metadata dictionary
    • image: Passed-through image

Advanced Features

Human-readable Text Format

The system can create human-readable text files for easy viewing:

# Enable human-readable text format
service = MetadataService(human_readable_text=True)

# Or change format at runtime
service.set_text_format(human_readable=True)

# Write metadata (will use human-readable format for text files)
service.write_metadata('path/to/image.png', metadata)

Example output:

Last update: 2025-03-15T10:23:45.123456
Metadata for image.png

Basic Information:
    Title: Mountain Landscape
    Description: AI generated mountain landscape
    Keywords: mountains, landscape, nature, AI

AI Generation Information:
    Prompt: majestic mountains with snow caps
    Negative prompt: ugly, blurry
    Model: stable-diffusion-v1-5
    Sampler: euler_a
    Steps: 30
    Cfg_scale: 7.5
    Seed: 1234567890

Database Queries

Perform advanced queries on the database:

from Metadata_system.handlers.db import DatabaseHandler

db = DatabaseHandler()

# Search for high-quality mountain images
results = db.search_images({
    'scores': [
        ('aesthetic', 'overall', '>', 7.0),
        ('technical', 'blur.score', '>', 0.8)
    ],
    'keywords': ['mountains'],
    'classifications': [('style', 'photorealistic')],
    'orientation': 'landscape',
    'order_by': 'images.created_date DESC',
    'limit': 10
})

# Process results
for image in results:
    print(f"Found image: {image['filepath']}")
    print(f"Rating: {image.get('rating', 'N/A')}")

Resource Identifiers

Set custom resource identifiers for XMP metadata:

# Set resource identifier for all handlers
service.set_resource_identifier("file:///custom/path/to/resource.jpg")

# Write metadata with custom resource identifier
service.write_metadata('path/to/image.jpg', metadata)

Batch Operations

Perform operations on multiple files:

# Using DatabaseHandler for batch operations
from Metadata_system.handlers.db import DatabaseHandler

db = DatabaseHandler()

# Define file paths
file_paths = [
    'path/to/image1.png',
    'path/to/image2.jpg',
    'path/to/image3.webp'
]

# Read metadata from multiple files
results = db.batch_operation('read', file_paths)

# Update metadata for multiple files
new_metadata = {
    'basic': {
        'keywords': ['batch', 'processed']
    }
}
results = db.batch_operation('write', file_paths, new_metadata)

# Check results
for filepath, success in results.items():
    print(f"{filepath}: {'Succeeded' if success else 'Failed'}")

Troubleshooting

Common Issues

Issue: Cannot write embedded metadata to PNG file Solution: Ensure PyExiv2 is installed or use ExifTool as a fallback

# Check if PyExiv2 is available
try:
    import pyexiv2
    print("PyExiv2 is available")
except ImportError:
    print("PyExiv2 is not available, using ExifTool fallback")

Issue: Files not showing metadata in other applications Solution: Verify format compatibility and try XMP sidecars

# Force write to XMP sidecar
service.write_metadata('path/to/image.png', metadata, targets=['xmp'])

Issue: Database errors Solution: Check SQLite installation and file permissions

# Use try-except to handle database errors
try:
    from Metadata_system.handlers.db import DatabaseHandler
    db = DatabaseHandler()
    # Operations with db
except Exception as e:
    print(f"Database error: {str(e)}")
    # Fall back to file-based storage
    service.write_metadata('path/to/image.png', metadata, targets=['embedded', 'xmp', 'txt'])

Debug Mode

Enable debug mode for detailed logging:

# Initialize with debug mode
service = MetadataService(debug=True)

# Operations will now produce detailed logs
service.write_metadata('path/to/image.png', metadata)

Debug logs include:

  • Format detection results
  • Handler selection details
  • Operation traces
  • Error messages with stack traces

Access error history from handlers:

# Get embedded handler
embedded_handler = service._get_embedded_handler()

# Print error history
for error in embedded_handler.error_history:
    print(f"[{error['timestamp']}] {error['level']}: {error['message']}")
    if error['error']:
        print(f"Error: {error['error']}")
    print("---")