import gradio as gr from PIL import Image import requests from io import BytesIO import json import html css = """ .html-container span { color: var(--color-accent); } .json-node { --string-color: #b5bd68; --separator-color: var(--block-border-color); } .json-node .null { color: var(--body-text-color-subdued); } .json-node .bool { color: #cc99cc; } """ NL = "\n" def parse_key_value_pairs(input_string): pairs = [] key = None value = "" brace_count = 0 in_string = False escaping = False for i, char in enumerate(input_string): if char == '"' and not escaping: in_string = not in_string elif char == "\\" and not escaping: escaping = True else: escaping = False if char == "{" and not in_string: brace_count += 1 elif char == "}" and not in_string: brace_count -= 1 if (char == "," and brace_count == 0 and not in_string) or i == len(input_string) - 1: if i == len(input_string) - 1: value += char if key is not None and value: pairs.append((key, value)) elif key is None and value and pairs: prev_key, prev_value = pairs.pop() pairs.append((prev_key, f"{prev_value},{value}")) key, value = None, "" elif char == ":" and brace_count == 0 and not in_string: key, value = value, "" else: value += char return [(k.strip(), v.strip()) for k, v in pairs] def process_webui(info_data): lines = info_data.split("\n") positive_prompt = [] negative_prompt = [] settings_params = [] current_section = "positive" for line in lines: if current_section == "positive" and line.startswith("Negative prompt: "): current_section = "negative" line = line[len("Negative prompt: "):] elif current_section != "settings" and line.startswith("Steps: "): current_section = "settings" if current_section == "positive": positive_prompt.append(line) elif current_section == "negative": negative_prompt.append(line) elif current_section == "settings": settings_params.append(line) html_data = f"""
Prompt: {html.escape(NL.join(positive_prompt)).replace(NL, '
')}
Negative prompt: {html.escape(NL.join(negative_prompt)).replace(NL, '
')}
{html.escape(key).replace(NL, '
')}: {html.escape(value).replace(NL, '
')}
Prompt: {html.escape(comment.get('prompt', '')).replace(NL, '
')}
Undesired Content: {html.escape(comment.get('uc', '')).replace(NL, '
')}
Resolution: {comment.get('width', '')}x{comment.get('height', '')}
Seed: {comment.get('seed', '')}
Steps: {comment.get('steps', '')}
Sampler: {comment.get('sampler', '')} ({comment.get('noise_schedule', '')})
Prompt Guidance: {comment.get('scale', '')}
Prompt Guidance Rescale: {comment.get('cfg_rescale', '')}
Undesired Content Strength: {comment.get('uncond_scale', '')}
Request Type: {comment.get('request_type', '')}
Software: {info_data.get('Software', '')}
Source: {info_data.get('Source', '')}
Title: {info_data.get('Title', '')}
Generation Time: {info_data.get('Generation time', info_data.get('Generation_time', ''))}
""" return html_data, comment def process_image(file=None, url=None): try: if url: response = requests.get(url) response.raise_for_status() img = Image.open(BytesIO(response.content)) elif file: img = file else: return ( "No input provided.", gr.update(visible=False), gr.update(visible=False), gr.update(visible=False) ) info_data = img.info if info_data: if "parameters" in info_data: parameters = info_data["parameters"] html_data = process_webui(parameters) return ( html_data, gr.update(visible=True, value=f"{html.escape(parameters).replace(NL, '
')}