Bulk Extraction of Metadata from PNG Files

Metadata based on generated PNGs in Automatic1111 (probably can be used for general files as well)


Firstly posted on a Reddit post, I thought it would be beneficial to share it here for a wider audience. My hope is this information will be useful.

A big thanks to ChatGPT for offering yet another insightful tip. Slowly but surely replacing "knowledgeable humans" one question at a time.

This script or tutorial is designed for extracting PNG metadata, particularly generated within Automatic1111. Depending on the WebUI you're using, you might need to adjust it slightly.

To pull out metadata from a collection of PNG files and save that data into a text file, you could use a blend of Python and the Python Imaging Library (PIL), or its descendant, Pillow. Below is a detailed guide to assist you through the process:

  1. Install the required libraries:
    pip install pillow
    
  2. Create a Python script (e.g., extract_metadata.py) and import the necessary modules:
    from PIL import Image
    import os
    
  3. Define the directory path where your PNG files are located and the output text file path:
    input_dir = "path/to/png/files"
    output_file = "path/to/output.txt"
    
  4. Open the output text file in write mode:
    with open(output_file, "w") as f:
        # Iterate over each file in the input directory
        for filename in os.listdir(input_dir):
            # Check if the file is a PNG file
            if filename.endswith(".png"):
                # Open the image file
                image_path = os.path.join(input_dir, filename)
                image = Image.open(image_path)
    
                # Extract the metadata
                metadata = image.info
    
                # Write the metadata to the text file
                f.write(f"File: {filename}\n")
                f.write(f"Metadata: {metadata}\n")
                f.write("\n")
    
                # Close the image file
                image.close()
    
  5. Once you've added the desired logic for handling the metadata, save and run the Python script:
    python extract_metadata.py
    

The script will iterate through all the PNG files in the specified directory, extract their metadata using PIL/Pillow, and write the file name and metadata to the output text file. Each file's metadata will be separated by a blank line.


As you notice from the above, it is a basic code extraction. I had to go back and forth with ChatGPT to get the following file. It is better looking and more readable. Separates each metadata nicely and adds a title as well:

New code:

import os
from PIL import Image

# Directory containing the PNG files
 input_dir = "path/to/png/files"

# Output file path
output_file = "path/to/output.txt"

# Open the output file in write mode
with open(output_file, "w") as f:
    # Iterate over each file in the directory
    for filename in os.listdir(directory):
        if filename.endswith(".png"):
            file_path = os.path.join(directory, filename)
            try:
                # Open the image file
                image = Image.open(file_path)

                # Get the metadata (EXIF) from the image
                metadata = image.info

                # Extract positive prompt and negative prompt
                positive_prompt = metadata["parameters"].split("\n")[0]
                negative_prompt = metadata["parameters"].split("\n")[1].split(": ")[1]

                # Find the index of the first occurrence of "Steps" in the parameters
                steps_index = metadata["parameters"].index("Steps:")

                # Extract the information from the first "Steps" onwards
                steps_info = metadata["parameters"][steps_index:].split("\nTemplate")[0]

                # Format the steps_info into separate key-value pairs
                steps_list = steps_info.split(", ")

                # Write the extracted information to the output file
                f.write(f"File: {filename}\n\n")
                f.write(f"Positive Prompt: {positive_prompt}\n\n")
                f.write(f"Negative Prompt: {negative_prompt}\n\n")

                # Write the formatted steps_info to the output file
                f.write("Configurations:\n")
                for step in steps_list:
                    f.write(f"{step}\n")

                f.write("---\n")

                # Close the image file
                image.close()
            except Exception as e:
                print(f"Error processing file: {filename}")
                print(e)

So now the original output goes from this:

File: 50-1007953940-20230526162755-alphones mucha girl warrior with curly green hair big piercing in the nouse standing with ghost deers warm colors art.png
{'parameters': 'alphones mucha girl warrior with curly green hair big piercing in the nouse standing with ghost deers warm colors art-nouveau on paper, smile, nature, fresco mucha flowers in the eyes bleach,8k, vivid colors,hdr\nNegative prompt: bad-picture-chill-75v, style-rustmagic-neg\nSteps: 50, Sampler: DPM++ SDE Karras, CFG scale: 10, Seed: 1007953940, Size: 512x768, Model hash: 4d91c4c217, Model: RA_lyriel_v15, Denoising strength: 0.5, Version: v1.2.1, Hires upscale: 2, Hires steps: 25, Hires upscaler: 4x-UltraSharp\nTemplate: alphones mucha girl warrior with curly green hair big piercing in the nouse standing with ghost deers warm colors art-nouveau on paper, smile, nature, fresco mucha flowers in the eyes bleach,8k, vivid colors,hdr\nNegative Template: bad-picture-chill-75v, style-rustmagic-neg'}

To this:

File: 50-1007953940-20230526162755-alphones mucha girl warrior with curly green hair big piercing in the nouse standing with ghost deers warm colors art.png

Positive Prompt: alphones mucha girl warrior with curly green hair big piercing in the nouse standing with ghost deers warm colors art-nouveau on paper, smile, nature, fresco mucha flowers in the eyes bleach,8k, vivid colors,hdr

Negative Prompt: bad-picture-chill-75v, style-rustmagic-neg

Configurations:
Steps: 50
Sampler: DPM++ SDE Karras
CFG scale: 10
Seed: 1007953940
Size: 512x768
Model hash: 4d91c4c217
Model: RA_lyriel_v15
Denoising strength: 0.5
Version: v1.2.1
Hires upscale: 2
Hires steps: 25
Hires upscaler: 4x-UltraSharp


Each png meta data will be separated

Make sure to replace "path/to/png/files" with the actual path to your PNG files directory and "path/to/output.txt" with the desired path and name for the output text file.

To-Do:

  • extract metadata in bulk to a file format that can be used in the Script section of A111 in the Prompts from the file for easier regeneration. so it will be in the following format per file:

    --prompt "alphones mucha girl warrior with curly green hair big piercing in the nouse standing with ghost deers warm colors art-nouveau on paper, smile, nature, fresco mucha flowers in the eyes bleach,8k, vivid colors,hdr" --negative_prompt "bad-picture-chill-75v, style-rustmagic-neg" --steps 50 --sampler_name "DPM++ SDE Karras" --cfg_scale 10 --seed 1007953940 --width 512 --height 768 --sd_model "RA_lyriel_v15"

Note: I added the code in Github.

Edit Report
Pub: 27 May 2023 02:26 UTC
Views: 514