File size: 2,924 Bytes
4c8ab86
821a65f
3c2ef44
 
 
 
 
821a65f
 
3c2ef44
 
 
 
 
821a65f
3c2ef44
821a65f
 
 
3c2ef44
821a65f
3c2ef44
821a65f
 
 
 
 
3c2ef44
821a65f
3c2ef44
821a65f
3c2ef44
 
821a65f
3c2ef44
 
 
 
821a65f
 
4c8ab86
 
821a65f
4c8ab86
3c2ef44
 
4c8ab86
 
3c2ef44
 
 
 
 
4c8ab86
3c2ef44
 
 
4c8ab86
 
3c2ef44
821a65f
3c2ef44
4c8ab86
3c2ef44
 
 
 
 
 
 
 
821a65f
 
3c2ef44
 
821a65f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import gradio as gr
from PIL import Image, PngImagePlugin
import io

def extract_metadata(image):
    """Extracts Stable Diffusion metadata from a PIL Image."""
    if image:
        # Access metadata using the 'info' dictionary
        metadata = image.info.get("parameters", "")
    else:
        metadata = ""
    return image, metadata

def update_metadata(image, new_metadata):
    """Updates the Stable Diffusion metadata in a PIL Image."""
    if image:
        # Create a PngInfo object to store metadata
        pnginfo = PngImagePlugin.PngInfo()
        pnginfo.add_text("parameters", new_metadata)

        # Save the image to a BytesIO object with the updated metadata
        output_bytes = io.BytesIO()
        image.save(output_bytes, format="PNG", pnginfo=pnginfo)
        output_bytes.seek(0)

        # Re-open the image from the BytesIO object to ensure Gradio displays the updated image
        updated_image = Image.open(output_bytes)

        return updated_image, new_metadata # Return updated PIL Image
    else:
        return None, ""

def clear_metadata(image, metadata):
    """Clears the Stable Diffusion Metadata."""
    return update_metadata(image, "")


def copy_metadata(metadata: str):
    """Copies the metadata to the clipboard (simulated in Gradio)."""
    metadata = metadata.strip()
    embed_index = metadata.find("\nUsed embeddings: ")
    if embed_index < 0:
        embed_index = metadata.find("\nUsed embeddings: ")  # Corrected typo
    if embed_index > 0:
        metadata = metadata[:embed_index]

    return metadata

def process_image(image):
    """Combines extraction and initial display."""
    return extract_metadata(image)


with gr.Blocks() as demo:
    gr.Markdown("# SD EXIF Editor (Gradio)")
    gr.Markdown("Upload a PNG image generated by Stable Diffusion WebUI (AUTOMATIC1111) to view and edit its metadata.")

    with gr.Row():
        with gr.Column():
            image_input = gr.Image(type="pil", label="Upload PNG Image")
            image_output = gr.Image(type="pil", label="Processed Image") # Keep as PIL

        with gr.Column():
            metadata_textbox = gr.Textbox(label="Metadata", lines=5)
            with gr.Row():
                copy_button = gr.Button("Copy Metadata")
                clear_button = gr.Button("Clear Metadata")
                save_button = gr.Button("Save Metadata")

    # --- Event Handling ---
    image_input.change(process_image, inputs=[image_input], outputs=[image_output, metadata_textbox])
    save_button.click(update_metadata, inputs=[image_input, metadata_textbox], outputs=[image_output, metadata_textbox])  # Use image_input
    clear_button.click(clear_metadata, inputs=[image_input, metadata_textbox], outputs=[image_output, metadata_textbox])  # Use image_input
    copy_button.click(copy_metadata, inputs=[metadata_textbox], outputs=[metadata_textbox])

demo.launch(share=True) # Enable public link