zenafey commited on
Commit
3a7cb85
1 Parent(s): bbf71d1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +80 -490
app.py CHANGED
@@ -1,442 +1,18 @@
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
- from threading import Thread
14
-
15
- class Prodia:
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
- def transform(self, params):
27
- response = self._post(f"{self.base}/sd/transform", params)
28
- return response.json()
29
-
30
- def controlnet(self, params):
31
- response = self._post(f"{self.base}/sd/controlnet", params)
32
- return response.json()
33
-
34
- def upscale(self, params):
35
- response = self._post(f"{self.base}/upscale", params)
36
- return response.json()
37
-
38
- def get_job(self, job_id):
39
- response = self._get(f"{self.base}/job/{job_id}")
40
- return response.json()
41
-
42
- def wait(self, job):
43
- job_result = job
44
-
45
- while job_result['status'] not in ['succeeded', 'failed']:
46
- time.sleep(0.5)
47
- job_result = self.get_job(job['job'])
48
-
49
- return job_result
50
-
51
- def list_models(self):
52
- response = self._get(f"{self.base}/sd/models")
53
- return response.json()
54
-
55
- def list_loras(self):
56
- response = self._get(f"{self.base}/sd/loras")
57
- return response.json()
58
-
59
- def _post(self, url, params):
60
- headers = {
61
- **self.headers,
62
- "Content-Type": "application/json"
63
- }
64
- response = requests.post(url, headers=headers, data=json.dumps(params))
65
-
66
- if response.status_code != 200:
67
- raise Exception(f"Bad Prodia Response: {response.status_code}")
68
-
69
- return response
70
-
71
- def _get(self, url):
72
- response = requests.get(url, headers=self.headers)
73
-
74
- if response.status_code != 200:
75
- raise Exception(f"Bad Prodia Response: {response.status_code}")
76
-
77
- return response
78
-
79
-
80
- def image_to_base64(image):
81
- # Convert the image to bytes
82
- buffered = BytesIO()
83
- image.save(buffered, format="PNG") # You can change format to PNG if needed
84
-
85
- # Encode the bytes to base64
86
- img_str = base64.b64encode(buffered.getvalue())
87
-
88
- return img_str.decode('utf-8') # Convert bytes to string
89
-
90
-
91
- def remove_id_and_ext(text):
92
- text = re.sub(r'\[.*\]$', '', text)
93
- extension = text[-12:].strip()
94
- if extension == "safetensors":
95
- text = text[:-13]
96
- elif extension == "ckpt":
97
- text = text[:-4]
98
- return text
99
-
100
-
101
- def get_data(text):
102
- results = {}
103
- patterns = {
104
- 'prompt': r'(.*)',
105
- 'negative_prompt': r'Negative prompt: (.*)',
106
- 'steps': r'Steps: (\d+),',
107
- 'seed': r'Seed: (\d+),',
108
- 'sampler': r'Sampler:\s*([^\s,]+(?:\s+[^\s,]+)*)',
109
- 'model': r'Model:\s*([^\s,]+)',
110
- 'cfg_scale': r'CFG scale:\s*([\d\.]+)',
111
- 'size': r'Size:\s*([0-9]+x[0-9]+)'
112
- }
113
- for key in ['prompt', 'negative_prompt', 'steps', 'seed', 'sampler', 'model', 'cfg_scale', 'size']:
114
- match = re.search(patterns[key], text)
115
- if match:
116
- results[key] = match.group(1)
117
- else:
118
- results[key] = None
119
- if results['size'] is not None:
120
- w, h = results['size'].split("x")
121
- results['w'] = w
122
- results['h'] = h
123
- else:
124
- results['w'] = None
125
- results['h'] = None
126
- return results
127
-
128
-
129
- def send_to_txt2img(image):
130
- result = {tabs: gr.Tabs.update(selected="t2i")}
131
-
132
- try:
133
- text = image.info['parameters']
134
- data = get_data(text)
135
- result[prompt] = gr.update(value=data['prompt'])
136
- result[negative_prompt] = gr.update(value=data['negative_prompt']) if data[
137
- 'negative_prompt'] is not None else gr.update()
138
- result[steps] = gr.update(value=int(data['steps'])) if data['steps'] is not None else gr.update()
139
- result[seed] = gr.update(value=int(data['seed'])) if data['seed'] is not None else gr.update()
140
- result[cfg_scale] = gr.update(value=float(data['cfg_scale'])) if data['cfg_scale'] is not None else gr.update()
141
- result[width] = gr.update(value=int(data['w'])) if data['w'] is not None else gr.update()
142
- result[height] = gr.update(value=int(data['h'])) if data['h'] is not None else gr.update()
143
- result[sampler] = gr.update(value=data['sampler']) if data['sampler'] is not None else gr.update()
144
- if data['model'] in model_names:
145
- result[model] = gr.update(value=model_names[data['model']])
146
- else:
147
- result[model] = gr.update()
148
- return result
149
-
150
- except Exception as e:
151
- print(e)
152
- result[prompt] = gr.update()
153
- result[negative_prompt] = gr.update()
154
- result[steps] = gr.update()
155
- result[seed] = gr.update()
156
- result[cfg_scale] = gr.update()
157
- result[width] = gr.update()
158
- result[height] = gr.update()
159
- result[sampler] = gr.update()
160
- result[model] = gr.update()
161
-
162
- return result
163
-
164
- def place_lora(current_prompt, lora_name):
165
- pattern = r"<lora:" + lora_name + r":.*?>"
166
-
167
- if re.search(pattern, current_prompt):
168
- yield re.sub(pattern, "", current_prompt)
169
- else:
170
- yield current_prompt + " <lora:" + lora_name + ":1> "
171
-
172
- prodia_client = Prodia(api_key=os.getenv("PRODIA_API_KEY"))
173
- model_list = prodia_client.list_models()
174
- lora_list = prodia_client.list_loras()
175
- model_names = {}
176
-
177
- for model_name in model_list:
178
- name_without_ext = remove_id_and_ext(model_name)
179
- model_names[name_without_ext] = model_name
180
-
181
-
182
- def txt2img(prompt, negative_prompt, model, steps, sampler, cfg_scale, width, height, seed, batch_count, gallery):
183
- yield {
184
- text_button: gr.update(visible=False),
185
- stop_btn: gr.update(visible=True),
186
- }
187
- data = {
188
- "prompt": prompt,
189
- "negative_prompt": negative_prompt,
190
- "model": model,
191
- "steps": steps,
192
- "sampler": sampler,
193
- "cfg_scale": cfg_scale,
194
- "width": width,
195
- "height": height,
196
- "seed": seed
197
- }
198
-
199
- total_images = []
200
- threads = []
201
-
202
- def generate_one_image():
203
- result = prodia_client.generate(data)
204
- job = prodia_client.wait(result)
205
- total_images.append(job['imageUrl'])
206
-
207
- for x in range(batch_count):
208
- t = Thread(target=generate_one_image)
209
- threads.append(t)
210
- t.start()
211
-
212
- for t in threads:
213
- t.join()
214
-
215
- new_images_list = [img['name'] for img in gallery]
216
-
217
- for image in total_images:
218
- new_images_list.insert(0, image)
219
-
220
- if batch_count > 1:
221
- results = gr.update(value=total_images, preview=False)
222
- else:
223
- results = gr.update(value=total_images, preview=True)
224
-
225
- yield {
226
- text_button: gr.update(visible=True),
227
- stop_btn: gr.update(visible=False),
228
- image_output: results,
229
- gallery_obj: gr.update(value=new_images_list),
230
- }
231
-
232
-
233
- def img2img(input_image, denoising, prompt, negative_prompt, model, steps, sampler, cfg_scale, width, height, seed,
234
- batch_count, gallery):
235
- if input_image is None:
236
- return
237
- yield {
238
- i2i_text_button: gr.update(visible=False),
239
- i2i_stop_btn: gr.update(visible=True),
240
- }
241
- data = {
242
- "imageData": image_to_base64(input_image),
243
- "denoising_strength": denoising,
244
- "prompt": prompt,
245
- "negative_prompt": negative_prompt,
246
- "model": model,
247
- "steps": steps,
248
- "sampler": sampler,
249
- "cfg_scale": cfg_scale,
250
- "width": width,
251
- "height": height,
252
- "seed": seed
253
- }
254
-
255
- total_images = []
256
- threads = []
257
-
258
- def generate_one_image():
259
- result = prodia_client.transform(data)
260
- job = prodia_client.wait(result)
261
- total_images.append(job['imageUrl'])
262
-
263
- for x in range(batch_count):
264
- t = Thread(target=generate_one_image)
265
- threads.append(t)
266
- t.start()
267
-
268
- for t in threads:
269
- t.join()
270
-
271
- new_images_list = [img['name'] for img in gallery]
272
-
273
- for image in total_images:
274
- new_images_list.insert(0, image)
275
-
276
- if batch_count > 1:
277
- results = gr.update(value=total_images, preview=False)
278
- else:
279
- results = gr.update(value=total_images, preview=True)
280
-
281
- yield {
282
- i2i_text_button: gr.update(visible=True),
283
- i2i_stop_btn: gr.update(visible=False),
284
- i2i_image_output: results,
285
- gallery_obj: gr.update(value=new_images_list),
286
- }
287
-
288
- def upscale_fn(image, scale):
289
- if image is None:
290
- return
291
- yield {
292
- upscale_btn: gr.update(visible=False),
293
- upscale_stop: gr.update(visible=True),
294
- }
295
- job = prodia_client.upscale({
296
- 'imageData': image_to_base64(image),
297
- 'resize': scale
298
- })
299
-
300
- result = prodia_client.wait(job)
301
- yield {
302
- upscale_output: result['imageUrl'],
303
- upscale_btn: gr.update(visible=True),
304
- upscale_stop: gr.update(visible=False)
305
- }
306
-
307
- def stop_upscale():
308
- return {
309
- upscale_btn: gr.update(visible=True),
310
- upscale_stop: gr.update(visible=False)
311
- }
312
-
313
- def stop_t2i():
314
- return {
315
- text_button: gr.update(visible=True),
316
- stop_btn: gr.update(visible=False)
317
- }
318
-
319
- def stop_i2i():
320
- return {
321
- i2i_text_button: gr.update(visible=True),
322
- i2i_stop_btn: gr.update(visible=False)
323
- }
324
-
325
-
326
-
327
- samplers = [
328
- "Euler",
329
- "Euler a",
330
- "LMS",
331
- "Heun",
332
- "DPM2",
333
- "DPM2 a",
334
- "DPM++ 2S a",
335
- "DPM++ 2M",
336
- "DPM++ SDE",
337
- "DPM fast",
338
- "DPM adaptive",
339
- "LMS Karras",
340
- "DPM2 Karras",
341
- "DPM2 a Karras",
342
- "DPM++ 2S a Karras",
343
- "DPM++ 2M Karras",
344
- "DPM++ SDE Karras",
345
- "DDIM",
346
- "PLMS",
347
- ]
348
-
349
- css = """
350
- :root, .dark{
351
- --checkbox-label-gap: 0.25em 0.1em;
352
- --section-header-text-size: 12pt;
353
- --block-background-fill: transparent;
354
- }
355
- .block.padded:not(.gradio-accordion) {
356
- padding: 0 !important;
357
- }
358
- div.gradio-container{
359
- max-width: unset !important;
360
- }
361
- .compact{
362
- background: transparent !important;
363
- padding: 0 !important;
364
- }
365
- div.form{
366
- border-width: 0;
367
- box-shadow: none;
368
- background: transparent;
369
- overflow: visible;
370
- gap: 0.5em;
371
- }
372
- .block.gradio-dropdown,
373
- .block.gradio-slider,
374
- .block.gradio-checkbox,
375
- .block.gradio-textbox,
376
- .block.gradio-radio,
377
- .block.gradio-checkboxgroup,
378
- .block.gradio-number,
379
- .block.gradio-colorpicker {
380
- border-width: 0 !important;
381
- box-shadow: none !important;
382
- }
383
- .gradio-dropdown label span:not(.has-info),
384
- .gradio-textbox label span:not(.has-info),
385
- .gradio-number label span:not(.has-info)
386
- {
387
- margin-bottom: 0;
388
- }
389
- .gradio-dropdown ul.options{
390
- z-index: 3000;
391
- min-width: fit-content;
392
- max-width: inherit;
393
- white-space: nowrap;
394
- }
395
- .gradio-dropdown ul.options li.item {
396
- padding: 0.05em 0;
397
- }
398
- .gradio-dropdown ul.options li.item.selected {
399
- background-color: var(--neutral-100);
400
- }
401
- .dark .gradio-dropdown ul.options li.item.selected {
402
- background-color: var(--neutral-900);
403
- }
404
- .gradio-dropdown div.wrap.wrap.wrap.wrap{
405
- box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
406
- }
407
- .gradio-dropdown:not(.multiselect) .wrap-inner.wrap-inner.wrap-inner{
408
- flex-wrap: unset;
409
- }
410
- .gradio-dropdown .single-select{
411
- white-space: nowrap;
412
- overflow: hidden;
413
- }
414
- .gradio-dropdown .token-remove.remove-all.remove-all{
415
- display: none;
416
- }
417
- .gradio-dropdown.multiselect .token-remove.remove-all.remove-all{
418
- display: flex;
419
- }
420
- .gradio-slider input[type="number"]{
421
- width: 6em;
422
- }
423
- .block.gradio-checkbox {
424
- margin: 0.75em 1.5em 0 0;
425
- }
426
- .gradio-html div.wrap{
427
- height: 100%;
428
- }
429
- div.gradio-html.min{
430
- min-height: 0;
431
- }
432
- #model_dd {
433
- width: 16%;
434
- }
435
- """
436
-
437
- with gr.Blocks(css=css) as demo:
438
- model = gr.Dropdown(interactive=True, value="absolutereality_v181.safetensors [3d9d4d2b]", show_label=True,
439
- label="Stable Diffusion Checkpoint", choices=prodia_client.list_models(), elem_id="model_dd")
440
 
441
  with gr.Tabs() as tabs:
442
  with gr.Tab("txt2img", id='t2i'):
@@ -447,8 +23,9 @@ with gr.Blocks(css=css) as demo:
447
  negative_prompt = gr.Textbox(placeholder="Negative Prompt", show_label=False, lines=3,
448
  value="3d, cartoon, anime, (deformed eyes, nose, ears, nose), bad anatomy, ugly")
449
  with gr.Row():
450
- text_button = gr.Button("Generate", variant='primary', elem_id="generate")
451
- stop_btn = gr.Button("Cancel", variant="stop", elem_id="generate", visible=False)
 
452
 
453
  with gr.Row():
454
  with gr.Column():
@@ -491,7 +68,7 @@ with gr.Blocks(css=css) as demo:
491
  i2i_negative_prompt = gr.Textbox(placeholder="Negative Prompt", show_label=False, lines=3,
492
  value="3d, cartoon, anime, (deformed eyes, nose, ears, nose), bad anatomy, ugly")
493
  with gr.Row():
494
- i2i_text_button = gr.Button("Generate", variant='primary', elem_id="generate")
495
  i2i_stop_btn = gr.Button("Cancel", variant="stop", elem_id="generate", visible=False)
496
 
497
  with gr.Row():
@@ -536,38 +113,13 @@ with gr.Blocks(css=css) as demo:
536
  with gr.Column():
537
  upscale_image_input = gr.Image(type="pil")
538
  upscale_btn = gr.Button("Generate", variant="primary")
539
- upscale_stop = gr.Button("Stop", variant="stop", visible=False)
540
  with gr.Tab("Scale by"):
541
- scale_by = gr.Radio([2, 4], value=2, label="Resize")
542
 
543
  upscale_output = gr.Image()
544
 
545
  with gr.Tab("PNG Info"):
546
- def plaintext_to_html(text, classname=None):
547
- content = "<br>\n".join(html.escape(x) for x in text.split('\n'))
548
-
549
- return f"<p class='{classname}'>{content}</p>" if classname else f"<p>{content}</p>"
550
-
551
-
552
- def get_exif_data(image):
553
- items = image.info
554
-
555
- info = ''
556
- for key, text in items.items():
557
- info += f"""
558
- <div>
559
- <p><b>{plaintext_to_html(str(key))}</b></p>
560
- <p>{plaintext_to_html(str(text))}</p>
561
- </div>
562
- """.strip() + "\n"
563
-
564
- if len(info) == 0:
565
- message = "Nothing found in the image."
566
- info = f"<div><p>{message}<p></div>"
567
-
568
- return info
569
-
570
-
571
  with gr.Row():
572
  with gr.Column():
573
  image_input = gr.Image(type="pil")
@@ -576,27 +128,65 @@ with gr.Blocks(css=css) as demo:
576
  exif_output = gr.HTML(label="EXIF Data")
577
  send_to_txt2img_btn = gr.Button("Send to txt2img")
578
 
579
- with gr.Tab("Gallery"):
580
- gallery_obj = gr.Gallery(height=1000, columns=6)
581
-
582
- t2i_event = text_button.click(txt2img,
583
- inputs=[prompt, negative_prompt, model, steps, sampler, cfg_scale, width, height,
584
- seed, batch_count, gallery_obj], outputs=[image_output, gallery_obj, text_button, stop_btn])
585
- stop_btn.click(fn=stop_t2i, outputs=[text_button, stop_btn], cancels=[t2i_event])
 
 
 
 
 
 
 
 
 
 
 
586
 
587
  image_input.upload(get_exif_data, inputs=[image_input], outputs=exif_output)
588
- send_to_txt2img_btn.click(send_to_txt2img, inputs=[image_input],
589
- outputs=[tabs, prompt, negative_prompt, steps, seed, model, sampler, width, height,
590
- cfg_scale])
591
-
592
- i2i_event = i2i_text_button.click(img2img,
593
- inputs=[i2i_image_input, i2i_denoising, i2i_prompt, i2i_negative_prompt,
594
- model, i2i_steps, i2i_sampler, i2i_cfg_scale, i2i_width, i2i_height,
595
- i2i_seed, i2i_batch_count, gallery_obj],
596
- outputs=[i2i_image_output, gallery_obj, i2i_text_button, i2i_stop_btn])
597
- i2i_stop_btn.click(fn=stop_i2i, outputs=[i2i_text_button, i2i_stop_btn], cancels=[i2i_event])
598
-
599
- upscale_event = upscale_btn.click(fn=upscale_fn, inputs=[upscale_image_input, scale_by], outputs=[upscale_output, upscale_btn, upscale_stop])
600
- upscale_stop.click(fn=stop_upscale, outputs=[upscale_btn, upscale_stop], cancels=[upscale_event])
601
 
602
- demo.queue().launch(max_threads=256)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # original code by zenafey
2
+
3
+ from utils import place_lora, get_exif_data
4
+ from css import css
5
+ from grutils import *
6
+ import inference
7
+
8
+
9
+ lora_list = pipe.constant("/sd/loras")
10
+ samplers = pipe.constant("/sd/samplers")
11
+
12
+
13
+ with gr.Blocks(css=css, theme="zenafey/prodia-web") as demo:
14
+ model = gr.Dropdown(interactive=True, value=model_list[0], show_label=True, label="Stable Diffusion Checkpoint",
15
+ choices=model_list, elem_id="model_dd")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
  with gr.Tabs() as tabs:
18
  with gr.Tab("txt2img", id='t2i'):
 
23
  negative_prompt = gr.Textbox(placeholder="Negative Prompt", show_label=False, lines=3,
24
  value="3d, cartoon, anime, (deformed eyes, nose, ears, nose), bad anatomy, ugly")
25
  with gr.Row():
26
+ t2i_generate_btn = gr.Button("Generate", variant='primary', elem_id="generate")
27
+
28
+ t2i_stop_btn = gr.Button("Cancel", variant="stop", elem_id="generate", visible=False)
29
 
30
  with gr.Row():
31
  with gr.Column():
 
68
  i2i_negative_prompt = gr.Textbox(placeholder="Negative Prompt", show_label=False, lines=3,
69
  value="3d, cartoon, anime, (deformed eyes, nose, ears, nose), bad anatomy, ugly")
70
  with gr.Row():
71
+ i2i_generate_btn = gr.Button("Generate", variant='primary', elem_id="generate")
72
  i2i_stop_btn = gr.Button("Cancel", variant="stop", elem_id="generate", visible=False)
73
 
74
  with gr.Row():
 
113
  with gr.Column():
114
  upscale_image_input = gr.Image(type="pil")
115
  upscale_btn = gr.Button("Generate", variant="primary")
116
+ upscale_stop_btn = gr.Button("Stop", variant="stop", visible=False)
117
  with gr.Tab("Scale by"):
118
+ upscale_scale = gr.Radio([2, 4], value=2, label="Resize")
119
 
120
  upscale_output = gr.Image()
121
 
122
  with gr.Tab("PNG Info"):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  with gr.Row():
124
  with gr.Column():
125
  image_input = gr.Image(type="pil")
 
128
  exif_output = gr.HTML(label="EXIF Data")
129
  send_to_txt2img_btn = gr.Button("Send to txt2img")
130
 
131
+ with gr.Tab("Past generations"):
132
+ inference.gr_user_history.render()
133
+
134
+ t2i_event_start = t2i_generate_btn.click(
135
+ update_btn_start,
136
+ outputs=[t2i_generate_btn, t2i_stop_btn]
137
+ )
138
+ t2i_event = t2i_event_start.then(
139
+ inference.txt2img,
140
+ inputs=[prompt, negative_prompt, model, steps, sampler, cfg_scale, width, height, seed, batch_count],
141
+ outputs=[image_output]
142
+ )
143
+ t2i_event_end = t2i_event.then(
144
+ update_btn_end,
145
+ outputs=[t2i_generate_btn, t2i_stop_btn]
146
+ )
147
+
148
+ t2i_stop_btn.click(fn=update_btn_end, outputs=[t2i_generate_btn, t2i_stop_btn], cancels=[t2i_event])
149
 
150
  image_input.upload(get_exif_data, inputs=[image_input], outputs=exif_output)
 
 
 
 
 
 
 
 
 
 
 
 
 
151
 
152
+ send_to_txt2img_btn.click(
153
+ fn=switch_to_t2i,
154
+ outputs=[tabs]
155
+ ).then(
156
+ fn=send_to_txt2img,
157
+ inputs=[image_input],
158
+ outputs=[prompt, negative_prompt, steps, seed, model, sampler, width, height, cfg_scale]
159
+ )
160
+
161
+ i2i_event_start = i2i_generate_btn.click(
162
+ update_btn_start,
163
+ outputs=[i2i_generate_btn, i2i_stop_btn]
164
+ )
165
+ i2i_event = i2i_event_start.then(inference.img2img,
166
+ inputs=[i2i_image_input, i2i_denoising, i2i_prompt, i2i_negative_prompt,
167
+ model, i2i_steps, i2i_sampler, i2i_cfg_scale, i2i_width, i2i_height,
168
+ i2i_seed, i2i_batch_count],
169
+ outputs=[i2i_image_output])
170
+ i2i_event_end = i2i_event.then(
171
+ update_btn_end,
172
+ outputs=[i2i_generate_btn, i2i_stop_btn]
173
+ )
174
+ i2i_stop_btn.click(fn=update_btn_end, outputs=[i2i_generate_btn, i2i_stop_btn], cancels=[i2i_event])
175
+
176
+ upscale_event_start = upscale_btn.click(
177
+ fn=update_btn_start,
178
+ outputs=[upscale_btn, upscale_stop_btn]
179
+ )
180
+ upscale_event = upscale_event_start.then(
181
+ fn=inference.upscale,
182
+ inputs=[upscale_image_input, upscale_scale],
183
+ outputs=[upscale_output]
184
+ )
185
+ upscale_event_end = upscale_event.then(
186
+ fn=update_btn_end,
187
+ outputs=[upscale_btn, upscale_stop_btn]
188
+ )
189
+
190
+ upscale_stop_btn.click(fn=update_btn_end, outputs=[upscale_btn, upscale_stop_btn], cancels=[upscale_event])
191
+
192
+ demo.queue().launch(max_threads=256)