horsey-defy commited on
Commit
9a46212
·
1 Parent(s): b8a8ac7

Updated to have more functions

Browse files
Files changed (1) hide show
  1. app.py +246 -4
app.py CHANGED
@@ -1,7 +1,249 @@
 
1
  import gradio as gr
 
 
 
 
 
 
 
 
 
 
2
 
3
- def greet(name):
4
- return "Hello " + name + "!!"
5
 
6
- iface = gr.Interface(fn=greet, inputs="text", outputs="text")
7
- iface.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
  import gradio as gr
3
+ import requests
4
+ import time
5
+ import json
6
+ import base64
7
+ import os
8
+ from io import BytesIO
9
+ import PIL
10
+ from PIL.ExifTags import TAGS
11
+ import html
12
+ import re
13
 
 
 
14
 
15
+ class RenderNet:
16
+ def __init__(self, api_key, base=None):
17
+ self.base = base or "https://api.prodia.com/v1"
18
+ self.headers = {
19
+ "X-Prodia-Key": api_key
20
+ }
21
+
22
+ def generate(self, params):
23
+ response = self._post(f"{self.base}/sd/generate", params)
24
+ return response.json()
25
+
26
+
27
+ def list_models(self):
28
+ response = self._get(f"{self.base}/sd/models")
29
+ return response.json()
30
+
31
+ def _post(self, url, params):
32
+ headers = {
33
+ **self.headers,
34
+ "Content-Type": "application/json"
35
+ }
36
+ response = requests.post(url, headers=headers, data=json.dumps(params))
37
+
38
+ if response.status_code != 200:
39
+ raise Exception(f"Bad Prodia Response: {response.status_code}")
40
+
41
+ return response
42
+
43
+ def _get(self, url):
44
+ response = requests.get(url, headers=self.headers)
45
+
46
+ if response.status_code != 200:
47
+ raise Exception(f"Bad Prodia Response: {response.status_code}")
48
+
49
+ return response
50
+
51
+
52
+ def image_to_base64(image):
53
+ # Convert the image to bytes
54
+ buffered = BytesIO()
55
+ image.save(buffered, format="PNG") # You can change format to PNG if needed
56
+
57
+ # Encode the bytes to base64
58
+ img_str = base64.b64encode(buffered.getvalue())
59
+
60
+ return img_str.decode('utf-8') # Convert bytes to string
61
+
62
+ def remove_id_and_ext(text):
63
+ text = re.sub(r'\[.*\]$', '', text)
64
+ extension = text[-12:].strip()
65
+ if extension == "safetensors":
66
+ text = text[:-13]
67
+ elif extension == "ckpt":
68
+ text = text[:-4]
69
+ return text
70
+
71
+ def get_data(text):
72
+ results = {}
73
+ patterns = {
74
+ 'prompt': r'(.*)',
75
+ 'negative_prompt': r'Negative prompt: (.*)',
76
+ 'steps': r'Steps: (\d+),',
77
+ 'seed': r'Seed: (\d+),',
78
+ 'sampler': r'Sampler:\s*([^\s,]+(?:\s+[^\s,]+)*)',
79
+ 'model': r'Model:\s*([^\s,]+)',
80
+ 'cfg_scale': r'CFG scale:\s*([\d\.]+)',
81
+ 'size': r'Size:\s*([0-9]+x[0-9]+)'
82
+ }
83
+ for key in ['prompt', 'negative_prompt', 'steps', 'seed', 'sampler', 'model', 'cfg_scale', 'size']:
84
+ match = re.search(patterns[key], text)
85
+ if match:
86
+ results[key] = match.group(1)
87
+ else:
88
+ results[key] = None
89
+ if results['size'] is not None:
90
+ w, h = results['size'].split("x")
91
+ results['w'] = w
92
+ results['h'] = h
93
+ else:
94
+ results['w'] = None
95
+ results['h'] = None
96
+ return results
97
+
98
+ def send_to_txt2img(image):
99
+
100
+ result = {tabs: gr.Tabs.update(selected="t2i")}
101
+
102
+ try:
103
+ text = image.info['parameters']
104
+ data = get_data(text)
105
+ result[prompt] = gr.update(value=data['prompt'])
106
+ result[negative_prompt] = gr.update(value=data['negative_prompt']) if data['negative_prompt'] is not None else gr.update()
107
+ result[steps] = gr.update(value=int(data['steps'])) if data['steps'] is not None else gr.update()
108
+ result[seed] = gr.update(value=int(data['seed'])) if data['seed'] is not None else gr.update()
109
+ result[cfg_scale] = gr.update(value=float(data['cfg_scale'])) if data['cfg_scale'] is not None else gr.update()
110
+ result[width] = gr.update(value=int(data['w'])) if data['w'] is not None else gr.update()
111
+ result[height] = gr.update(value=int(data['h'])) if data['h'] is not None else gr.update()
112
+ result[sampler] = gr.update(value=data['sampler']) if data['sampler'] is not None else gr.update()
113
+ if model in model_names:
114
+ result[model] = gr.update(value=model_names[model])
115
+ else:
116
+ result[model] = gr.update()
117
+ return result
118
+
119
+ except Exception as e:
120
+ print(e)
121
+ result[prompt] = gr.update()
122
+ result[negative_prompt] = gr.update()
123
+ result[steps] = gr.update()
124
+ result[seed] = gr.update()
125
+ result[cfg_scale] = gr.update()
126
+ result[width] = gr.update()
127
+ result[height] = gr.update()
128
+ result[sampler] = gr.update()
129
+ result[model] = gr.update()
130
+
131
+ return result
132
+
133
+
134
+ prodia_client = Prodia(api_key=os.getenv("PRODIA_API_KEY"))
135
+ model_list = prodia_client.list_models()
136
+ model_names = {}
137
+
138
+ for model_name in model_list:
139
+ name_without_ext = remove_id_and_ext(model_name)
140
+ model_names[name_without_ext] = model_name
141
+
142
+ def txt2img(prompt, negative_prompt, model, steps, sampler, cfg_scale, width, height, seed):
143
+ result = prodia_client.generate({
144
+ "prompt": prompt,
145
+ "negative_prompt": negative_prompt,
146
+ "model": model,
147
+ "steps": steps,
148
+ "sampler": sampler,
149
+ "cfg_scale": cfg_scale,
150
+ "width": width,
151
+ "height": height,
152
+ "seed": seed
153
+ })
154
+
155
+ job = prodia_client.wait(result)
156
+
157
+ return job["imageUrl"]
158
+
159
+
160
+ css = """
161
+ #generate {
162
+ height: 100%;
163
+ }
164
+ """
165
+
166
+ with gr.Blocks(css=css) as demo:
167
+ with gr.Row():
168
+ with gr.Column(scale=6):
169
+ model = gr.Dropdown(interactive=True,value="absolutereality_v181.safetensors [3d9d4d2b]", show_label=True, label="Stable Diffusion Checkpoint", choices=prodia_client.list_models())
170
+
171
+ with gr.Column(scale=1):
172
+ gr.Markdown(elem_id="powered-by-prodia", value="AUTOMATIC1111 Stable Diffusion Web UI.<br>Powered by [Prodia](https://prodia.com).<br>For more features and faster generation times check out our [API Docs](https://docs.prodia.com/reference/getting-started-guide).")
173
+
174
+
175
+ with gr.Tabs() as tabs:
176
+ with gr.Tab("txt2img", id='t2i'):
177
+ with gr.Row():
178
+ with gr.Column(scale=6, min_width=600):
179
+ prompt = gr.Textbox("space warrior, beautiful, female, ultrarealistic, soft lighting, 8k", placeholder="Prompt", show_label=False, lines=3)
180
+ negative_prompt = gr.Textbox(placeholder="Negative Prompt", show_label=False, lines=3, value="3d, cartoon, anime, (deformed eyes, nose, ears, nose), bad anatomy, ugly")
181
+ with gr.Column():
182
+ text_button = gr.Button("Generate", variant='primary', elem_id="generate")
183
+
184
+ with gr.Row():
185
+ with gr.Column(scale=3):
186
+ with gr.Tab("Generation"):
187
+ with gr.Row():
188
+ with gr.Column(scale=1):
189
+ sampler = gr.Dropdown(value="DPM++ 2M Karras", show_label=True, label="Sampling Method", choices=prodia_client.list_samplers())
190
+
191
+ with gr.Column(scale=1):
192
+ steps = gr.Slider(label="Sampling Steps", minimum=1, maximum=30, value=25, step=1)
193
+
194
+ with gr.Row():
195
+ with gr.Column(scale=1):
196
+ width = gr.Slider(label="Width", maximum=1024, value=512, step=8)
197
+ height = gr.Slider(label="Height", maximum=1024, value=512, step=8)
198
+
199
+ with gr.Column(scale=1):
200
+ batch_size = gr.Slider(label="Batch Size", maximum=1, value=1)
201
+ batch_count = gr.Slider(label="Batch Count", maximum=1, value=1)
202
+
203
+ cfg_scale = gr.Slider(label="CFG Scale", minimum=1, maximum=20, value=7, step=1)
204
+ seed = gr.Number(label="Seed", value=-1)
205
+
206
+
207
+ with gr.Column(scale=2):
208
+ image_output = gr.Image(value="https://images.prodia.xyz/8ede1a7c-c0ee-4ded-987d-6ffed35fc477.png")
209
+
210
+ text_button.click(txt2img, inputs=[prompt, negative_prompt, model, steps, sampler, cfg_scale, width, height, seed], outputs=image_output)
211
+
212
+ with gr.Tab("PNG Info"):
213
+ def plaintext_to_html(text, classname=None):
214
+ content = "<br>\n".join(html.escape(x) for x in text.split('\n'))
215
+
216
+ return f"<p class='{classname}'>{content}</p>" if classname else f"<p>{content}</p>"
217
+
218
+
219
+ def get_exif_data(image):
220
+ items = image.info
221
+
222
+ info = ''
223
+ for key, text in items.items():
224
+ info += f"""
225
+ <div>
226
+ <p><b>{plaintext_to_html(str(key))}</b></p>
227
+ <p>{plaintext_to_html(str(text))}</p>
228
+ </div>
229
+ """.strip()+"\n"
230
+
231
+ if len(info) == 0:
232
+ message = "Nothing found in the image."
233
+ info = f"<div><p>{message}<p></div>"
234
+
235
+ return info
236
+
237
+ with gr.Row():
238
+ with gr.Column():
239
+ image_input = gr.Image(type="pil")
240
+
241
+ with gr.Column():
242
+ exif_output = gr.HTML(label="EXIF Data")
243
+ send_to_txt2img_btn = gr.Button("Send to txt2img")
244
+
245
+ image_input.upload(get_exif_data, inputs=[image_input], outputs=exif_output)
246
+ send_to_txt2img_btn.click(send_to_txt2img, inputs=[image_input], outputs=[tabs, prompt, negative_prompt, steps, seed,
247
+ model, sampler, width, height, cfg_scale])
248
+
249
+ demo.queue(concurrency_count=64, max_size=80, api_open=False).launch(max_threads=256)