zenafey commited on
Commit
7ae7416
1 Parent(s): b25462b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +337 -129
app.py CHANGED
@@ -1,20 +1,20 @@
1
  import numpy as np
2
  import gradio as gr
3
  import requests
4
- import random
5
  import time
6
  import json
7
  import base64
8
  import os
9
  from io import BytesIO
10
- import math
11
  import PIL
12
- from PIL import Image
13
  from PIL.ExifTags import TAGS
14
  import html
15
  import re
16
  from threading import Thread
17
 
 
 
 
18
  class Prodia:
19
  def __init__(self, api_key, base=None):
20
  self.base = base or "https://api.prodia.com/v1"
@@ -34,6 +34,10 @@ class Prodia:
34
  response = self._post(f"{self.base}/sd/controlnet", params)
35
  return response.json()
36
 
 
 
 
 
37
  def get_job(self, job_id):
38
  response = self._get(f"{self.base}/job/{job_id}")
39
  return response.json()
@@ -42,7 +46,7 @@ class Prodia:
42
  job_result = job
43
 
44
  while job_result['status'] not in ['succeeded', 'failed']:
45
- time.sleep(0.25)
46
  job_result = self.get_job(job['job'])
47
 
48
  return job_result
@@ -76,15 +80,13 @@ class Prodia:
76
  return response
77
 
78
 
79
- def image_to_base64(image_path):
80
- # Open the image with PIL
81
- with Image.open(image_path) as image:
82
- # Convert the image to bytes
83
- buffered = BytesIO()
84
- image.save(buffered, format="PNG") # You can change format to PNG if needed
85
 
86
- # Encode the bytes to base64
87
- img_str = base64.b64encode(buffered.getvalue())
88
 
89
  return img_str.decode('utf-8') # Convert bytes to string
90
 
@@ -98,43 +100,6 @@ def remove_id_and_ext(text):
98
  text = text[:-4]
99
  return text
100
 
101
- def place_lora(current_prompt, lora_name):
102
- pattern = r"<lora:" + lora_name + r":.*?>"
103
-
104
- if re.search(pattern, current_prompt):
105
- return re.sub(pattern, "", current_prompt)
106
- else:
107
- return current_prompt + "<lora:" + lora_name + ":1>"
108
-
109
- def create_grid(image_urls):
110
- # Download first image to get size
111
- response = requests.get(image_urls[0])
112
- img_data = response.content
113
- img = Image.open(BytesIO(img_data))
114
- w, h = img.size
115
-
116
- # Calculate rows and cols
117
- num_images = len(image_urls)
118
- num_cols = min(num_images, 3)
119
- num_rows = math.ceil(num_images / num_cols)
120
-
121
- # Create new rgba image
122
- grid_w = num_cols * w
123
- grid_h = num_rows * h
124
- grid = Image.new('RGBA', (grid_w, grid_h), (0, 0, 0, 0))
125
-
126
- # Download images and paste into grid
127
- for index, img_url in enumerate(image_urls):
128
- response = requests.get(img_url)
129
- img_data = response.content
130
- img = Image.open(BytesIO(img_data))
131
-
132
- row = index // num_cols
133
- col = index % num_cols
134
- grid.paste(img, (col * w, row * h))
135
-
136
- # Save image
137
- return grid
138
 
139
  def get_data(text):
140
  results = {}
@@ -199,9 +164,17 @@ def send_to_txt2img(image):
199
 
200
  return result
201
 
 
 
 
 
 
 
 
202
 
203
  prodia_client = Prodia(api_key=os.getenv("PRODIA_API_KEY"))
204
  model_list = prodia_client.list_models()
 
205
  model_names = {}
206
 
207
  for model_name in model_list:
@@ -209,10 +182,11 @@ for model_name in model_list:
209
  model_names[name_without_ext] = model_name
210
 
211
 
212
-
213
-
214
- def flip_text(prompt, negative_prompt, model, steps, sampler, cfg_scale, width, height, seed, batch_size, batch_count, gallery):
215
-
 
216
  data = {
217
  "prompt": prompt,
218
  "negative_prompt": negative_prompt,
@@ -222,41 +196,79 @@ def flip_text(prompt, negative_prompt, model, steps, sampler, cfg_scale, width,
222
  "cfg_scale": cfg_scale,
223
  "width": width,
224
  "height": height,
225
- "seed": seed,
226
- "upscale": True
227
  }
228
 
229
  total_images = []
230
- count_threads = []
231
 
232
- def generate_one_grid():
233
- grid_images = []
234
- size_threads = []
 
235
 
236
- def generate_one_image():
 
 
 
237
 
238
- result = prodia_client.generate(data)
 
 
 
 
 
 
239
 
240
- job = prodia_client.wait(result)
 
 
 
 
 
 
 
 
 
 
241
 
242
- grid_images.append(job['imageUrl'])
243
 
244
- for y in range(batch_size):
245
- t = Thread(target=generate_one_image)
246
- size_threads.append(t)
247
- t.start()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
248
 
249
- for t in size_threads:
250
- t.join()
251
 
252
- total_images.append(create_grid(grid_images))
 
 
 
253
 
254
  for x in range(batch_count):
255
- t = Thread(target=generate_one_grid)
256
- count_threads.append(t)
257
  t.start()
258
 
259
- for t in count_threads:
260
  t.join()
261
 
262
  new_images_list = [img['name'] for img in gallery]
@@ -264,89 +276,274 @@ def flip_text(prompt, negative_prompt, model, steps, sampler, cfg_scale, width,
264
  for image in total_images:
265
  new_images_list.insert(0, image)
266
 
267
- return {image_output: total_images, gallery_obj: new_images_list}
 
 
 
268
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
269
 
270
  css = """
271
- #model_dropdown {
272
- width: 50%;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
273
  }
274
  """
275
 
276
  with gr.Blocks(css=css) as demo:
277
- with gr.Row(elem_id="model_dropdown"):
278
- with gr.Column(scale=2):
279
- model = gr.Dropdown(interactive=True, value="absolutereality_v181.safetensors [3d9d4d2b]",
280
- label="Stable Diffusion Checkpoint", choices=prodia_client.list_models(), container=False)
281
-
282
- with gr.Column(scale=6):
283
- gr.Markdown(elem_id="powered-by-prodia",
284
- value="AUTOMATIC1111 Stable Diffusion Web UI.<br>Powered by [Prodia](https://prodia.com).<br> For more features and faster gen times check out our [API Docs](https://docs.prodia.com/reference/getting-started-guide)")
285
 
286
  with gr.Tabs() as tabs:
287
- with gr.Tab("txt2img", id='t2i', container=False):
288
  with gr.Row():
289
- with gr.Column(scale=4, min_width=600):
290
  prompt = gr.Textbox("space warrior, beautiful, female, ultrarealistic, soft lighting, 8k",
291
- placeholder="Prompt", show_label=False, lines=3, container=False)
292
- negative_prompt = gr.Textbox(placeholder="Negative Prompt", show_label=False, lines=3, container=False,
293
  value="3d, cartoon, anime, (deformed eyes, nose, ears, nose), bad anatomy, ugly")
294
- with gr.Row(scale=6):
295
  text_button = gr.Button("Generate", variant='primary', elem_id="generate")
296
- stop_btn = gr.Button("Cancel", elem_id="cancel")
297
 
298
  with gr.Row():
299
- with gr.Column(scale=3):
300
  with gr.Tab("Generation"):
301
  with gr.Row():
302
  with gr.Column(scale=1):
303
- sampler = gr.Dropdown(value="Euler a", show_label=True, label="Sampling Method",
304
- choices=[
305
- "Euler",
306
- "Euler a",
307
- "LMS",
308
- "Heun",
309
- "DPM2",
310
- "DPM2 a",
311
- "DPM++ 2S a",
312
- "DPM++ 2M",
313
- "DPM++ SDE",
314
- "DPM fast",
315
- "DPM adaptive",
316
- "LMS Karras",
317
- "DPM2 Karras",
318
- "DPM2 a Karras",
319
- "DPM++ 2S a Karras",
320
- "DPM++ 2M Karras",
321
- "DPM++ SDE Karras",
322
- "DDIM",
323
- "PLMS",
324
- ])
325
 
326
  with gr.Column(scale=1):
327
  steps = gr.Slider(label="Sampling Steps", minimum=1, maximum=30, value=25, step=1)
328
 
329
  with gr.Row():
330
- with gr.Column(scale=1):
331
  width = gr.Slider(label="Width", maximum=1024, value=512, step=8)
332
  height = gr.Slider(label="Height", maximum=1024, value=512, step=8)
333
 
334
  with gr.Column(scale=1):
335
- batch_size = gr.Slider(label="Batch Size", minimum=1, maximum=9, value=1, step=1)
336
- batch_count = gr.Slider(label="Batch Count", minimum=1, maximum=100, value=1, step=1)
337
 
338
  cfg_scale = gr.Slider(label="CFG Scale", minimum=1, maximum=20, value=7, step=1)
339
  seed = gr.Number(label="Seed", value=-1)
340
 
341
  with gr.Tab("Lora"):
342
- loralist = prodia_client.list_loras()
343
  with gr.Row():
344
- for lora in loralist:
345
  lora_btn = gr.Button(lora, size="sm")
346
  lora_btn.click(place_lora, inputs=[prompt, lora_btn], outputs=prompt)
347
 
348
- with gr.Column(scale=2):
349
- image_output = gr.Gallery(value=["https://images.prodia.xyz/8ede1a7c-c0ee-4ded-987d-6ffed35fc477.png"], preview=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
350
 
351
  with gr.Tab("PNG Info"):
352
  def plaintext_to_html(text, classname=None):
@@ -373,6 +570,7 @@ with gr.Blocks(css=css) as demo:
373
 
374
  return info
375
 
 
376
  with gr.Row():
377
  with gr.Column():
378
  image_input = gr.Image(type="pil")
@@ -382,16 +580,26 @@ with gr.Blocks(css=css) as demo:
382
  send_to_txt2img_btn = gr.Button("Send to txt2img")
383
 
384
  with gr.Tab("Gallery"):
385
- gallery_obj = gr.Gallery(height=1000, columns=5)
 
 
 
 
 
386
 
387
- generation_event = text_button.click(flip_text,
388
- inputs=[prompt, negative_prompt, model, steps, sampler, cfg_scale, width, height, seed, batch_size, batch_count,
389
- gallery_obj], outputs=[image_output, gallery_obj])
390
- stop_btn.click(fn=None, outputs=None, cancels=[generation_event])
391
  image_input.upload(get_exif_data, inputs=[image_input], outputs=exif_output)
392
  send_to_txt2img_btn.click(send_to_txt2img, inputs=[image_input],
393
- outputs=[tabs, prompt, negative_prompt, steps, seed,
394
- model, sampler, width, height, cfg_scale])
 
 
 
 
 
 
 
 
 
 
395
 
396
- demo.queue(concurrency_count=32)
397
- demo.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
  from threading import Thread
14
 
15
+ from dotenv import load_dotenv
16
+ load_dotenv()
17
+
18
  class Prodia:
19
  def __init__(self, api_key, base=None):
20
  self.base = base or "https://api.prodia.com/v1"
 
34
  response = self._post(f"{self.base}/sd/controlnet", params)
35
  return response.json()
36
 
37
+ def upscale(self, params):
38
+ response = self._post(f"{self.base}/upscale", params)
39
+ return response.json()
40
+
41
  def get_job(self, job_id):
42
  response = self._get(f"{self.base}/job/{job_id}")
43
  return response.json()
 
46
  job_result = job
47
 
48
  while job_result['status'] not in ['succeeded', 'failed']:
49
+ time.sleep(0.5)
50
  job_result = self.get_job(job['job'])
51
 
52
  return job_result
 
80
  return response
81
 
82
 
83
+ def image_to_base64(image):
84
+ # Convert the image to bytes
85
+ buffered = BytesIO()
86
+ image.save(buffered, format="PNG") # You can change format to PNG if needed
 
 
87
 
88
+ # Encode the bytes to base64
89
+ img_str = base64.b64encode(buffered.getvalue())
90
 
91
  return img_str.decode('utf-8') # Convert bytes to string
92
 
 
100
  text = text[:-4]
101
  return text
102
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
 
104
  def get_data(text):
105
  results = {}
 
164
 
165
  return result
166
 
167
+ def place_lora(current_prompt, lora_name):
168
+ pattern = r"<lora:" + lora_name + r":.*?>"
169
+
170
+ if re.search(pattern, current_prompt):
171
+ yield re.sub(pattern, "", current_prompt)
172
+ else:
173
+ yield current_prompt + " <lora:" + lora_name + ":1> "
174
 
175
  prodia_client = Prodia(api_key=os.getenv("PRODIA_API_KEY"))
176
  model_list = prodia_client.list_models()
177
+ lora_list = prodia_client.list_loras()
178
  model_names = {}
179
 
180
  for model_name in model_list:
 
182
  model_names[name_without_ext] = model_name
183
 
184
 
185
+ def txt2img(prompt, negative_prompt, model, steps, sampler, cfg_scale, width, height, seed, batch_count, gallery):
186
+ yield {
187
+ text_button: gr.update(visible=False),
188
+ stop_btn: gr.update(visible=True),
189
+ }
190
  data = {
191
  "prompt": prompt,
192
  "negative_prompt": negative_prompt,
 
196
  "cfg_scale": cfg_scale,
197
  "width": width,
198
  "height": height,
199
+ "seed": seed
 
200
  }
201
 
202
  total_images = []
203
+ threads = []
204
 
205
+ def generate_one_image():
206
+ result = prodia_client.generate(data)
207
+ job = prodia_client.wait(result)
208
+ total_images.append(job['imageUrl'])
209
 
210
+ for x in range(batch_count):
211
+ t = Thread(target=generate_one_image)
212
+ threads.append(t)
213
+ t.start()
214
 
215
+ for t in threads:
216
+ t.join()
217
+
218
+ new_images_list = [img['name'] for img in gallery]
219
+
220
+ for image in total_images:
221
+ new_images_list.insert(0, image)
222
 
223
+ if batch_count > 1:
224
+ results = gr.update(value=total_images, preview=False)
225
+ else:
226
+ results = gr.update(value=total_images, preview=True)
227
+
228
+ yield {
229
+ text_button: gr.update(visible=True),
230
+ stop_btn: gr.update(visible=False),
231
+ image_output: results,
232
+ gallery_obj: gr.update(value=new_images_list),
233
+ }
234
 
 
235
 
236
+ def img2img(input_image, denoising, prompt, negative_prompt, model, steps, sampler, cfg_scale, width, height, seed,
237
+ batch_count, gallery):
238
+ if input_image is None:
239
+ return
240
+ yield {
241
+ i2i_text_button: gr.update(visible=False),
242
+ i2i_stop_btn: gr.update(visible=True),
243
+ }
244
+ data = {
245
+ "imageData": image_to_base64(input_image),
246
+ "denoising_strength": denoising,
247
+ "prompt": prompt,
248
+ "negative_prompt": negative_prompt,
249
+ "model": model,
250
+ "steps": steps,
251
+ "sampler": sampler,
252
+ "cfg_scale": cfg_scale,
253
+ "width": width,
254
+ "height": height,
255
+ "seed": seed
256
+ }
257
 
258
+ total_images = []
259
+ threads = []
260
 
261
+ def generate_one_image():
262
+ result = prodia_client.transform(data)
263
+ job = prodia_client.wait(result)
264
+ total_images.append(job['imageUrl'])
265
 
266
  for x in range(batch_count):
267
+ t = Thread(target=generate_one_image)
268
+ threads.append(t)
269
  t.start()
270
 
271
+ for t in threads:
272
  t.join()
273
 
274
  new_images_list = [img['name'] for img in gallery]
 
276
  for image in total_images:
277
  new_images_list.insert(0, image)
278
 
279
+ if batch_count > 1:
280
+ results = gr.update(value=total_images, preview=False)
281
+ else:
282
+ results = gr.update(value=total_images, preview=True)
283
 
284
+ yield {
285
+ i2i_text_button: gr.update(visible=True),
286
+ i2i_stop_btn: gr.update(visible=False),
287
+ i2i_image_output: results,
288
+ gallery_obj: gr.update(value=new_images_list),
289
+ }
290
+
291
+ def upscale_fn(image, scale):
292
+ if image is None:
293
+ return
294
+ yield {
295
+ upscale_btn: gr.update(visible=False),
296
+ upscale_stop: gr.update(visible=True),
297
+ }
298
+ job = prodia_client.upscale({
299
+ 'imageData': image_to_base64(image),
300
+ 'resize': scale
301
+ })
302
+
303
+ result = prodia_client.wait(job)
304
+ yield {
305
+ upscale_output: result['imageUrl'],
306
+ upscale_btn: gr.update(visible=True),
307
+ upscale_stop: gr.update(visible=False)
308
+ }
309
+
310
+ def stop_upscale():
311
+ return {
312
+ upscale_btn: gr.update(visible=True),
313
+ upscale_stop: gr.update(visible=False)
314
+ }
315
+
316
+ def stop_t2i():
317
+ return {
318
+ text_button: gr.update(visible=True),
319
+ stop_btn: gr.update(visible=False)
320
+ }
321
+
322
+ def stop_i2i():
323
+ return {
324
+ i2i_text_button: gr.update(visible=True),
325
+ i2i_stop_btn: gr.update(visible=False)
326
+ }
327
+
328
+
329
+
330
+ samplers = [
331
+ "Euler",
332
+ "Euler a",
333
+ "LMS",
334
+ "Heun",
335
+ "DPM2",
336
+ "DPM2 a",
337
+ "DPM++ 2S a",
338
+ "DPM++ 2M",
339
+ "DPM++ SDE",
340
+ "DPM fast",
341
+ "DPM adaptive",
342
+ "LMS Karras",
343
+ "DPM2 Karras",
344
+ "DPM2 a Karras",
345
+ "DPM++ 2S a Karras",
346
+ "DPM++ 2M Karras",
347
+ "DPM++ SDE Karras",
348
+ "DDIM",
349
+ "PLMS",
350
+ ]
351
 
352
  css = """
353
+ :root, .dark{
354
+ --checkbox-label-gap: 0.25em 0.1em;
355
+ --section-header-text-size: 12pt;
356
+ --block-background-fill: transparent;
357
+ }
358
+ .block.padded:not(.gradio-accordion) {
359
+ padding: 0 !important;
360
+ }
361
+ div.gradio-container{
362
+ max-width: unset !important;
363
+ }
364
+ .compact{
365
+ background: transparent !important;
366
+ padding: 0 !important;
367
+ }
368
+ div.form{
369
+ border-width: 0;
370
+ box-shadow: none;
371
+ background: transparent;
372
+ overflow: visible;
373
+ gap: 0.5em;
374
+ }
375
+ .block.gradio-dropdown,
376
+ .block.gradio-slider,
377
+ .block.gradio-checkbox,
378
+ .block.gradio-textbox,
379
+ .block.gradio-radio,
380
+ .block.gradio-checkboxgroup,
381
+ .block.gradio-number,
382
+ .block.gradio-colorpicker {
383
+ border-width: 0 !important;
384
+ box-shadow: none !important;
385
+ }
386
+ .gradio-dropdown label span:not(.has-info),
387
+ .gradio-textbox label span:not(.has-info),
388
+ .gradio-number label span:not(.has-info)
389
+ {
390
+ margin-bottom: 0;
391
+ }
392
+ .gradio-dropdown ul.options{
393
+ z-index: 3000;
394
+ min-width: fit-content;
395
+ max-width: inherit;
396
+ white-space: nowrap;
397
+ }
398
+ .gradio-dropdown ul.options li.item {
399
+ padding: 0.05em 0;
400
+ }
401
+ .gradio-dropdown ul.options li.item.selected {
402
+ background-color: var(--neutral-100);
403
+ }
404
+ .dark .gradio-dropdown ul.options li.item.selected {
405
+ background-color: var(--neutral-900);
406
+ }
407
+ .gradio-dropdown div.wrap.wrap.wrap.wrap{
408
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
409
+ }
410
+ .gradio-dropdown:not(.multiselect) .wrap-inner.wrap-inner.wrap-inner{
411
+ flex-wrap: unset;
412
+ }
413
+ .gradio-dropdown .single-select{
414
+ white-space: nowrap;
415
+ overflow: hidden;
416
+ }
417
+ .gradio-dropdown .token-remove.remove-all.remove-all{
418
+ display: none;
419
+ }
420
+ .gradio-dropdown.multiselect .token-remove.remove-all.remove-all{
421
+ display: flex;
422
+ }
423
+ .gradio-slider input[type="number"]{
424
+ width: 6em;
425
+ }
426
+ .block.gradio-checkbox {
427
+ margin: 0.75em 1.5em 0 0;
428
+ }
429
+ .gradio-html div.wrap{
430
+ height: 100%;
431
+ }
432
+ div.gradio-html.min{
433
+ min-height: 0;
434
+ }
435
+ #model_dd {
436
+ width: 16%;
437
  }
438
  """
439
 
440
  with gr.Blocks(css=css) as demo:
441
+ model = gr.Dropdown(interactive=True, value="absolutereality_v181.safetensors [3d9d4d2b]", show_label=True,
442
+ label="Stable Diffusion Checkpoint", choices=prodia_client.list_models(), elem_id="model_dd")
 
 
 
 
 
 
443
 
444
  with gr.Tabs() as tabs:
445
+ with gr.Tab("txt2img", id='t2i'):
446
  with gr.Row():
447
+ with gr.Column(scale=6, min_width=600):
448
  prompt = gr.Textbox("space warrior, beautiful, female, ultrarealistic, soft lighting, 8k",
449
+ placeholder="Prompt", show_label=False, lines=3)
450
+ negative_prompt = gr.Textbox(placeholder="Negative Prompt", show_label=False, lines=3,
451
  value="3d, cartoon, anime, (deformed eyes, nose, ears, nose), bad anatomy, ugly")
452
+ with gr.Row():
453
  text_button = gr.Button("Generate", variant='primary', elem_id="generate")
454
+ stop_btn = gr.Button("Cancel", variant="stop", elem_id="generate", visible=False)
455
 
456
  with gr.Row():
457
+ with gr.Column():
458
  with gr.Tab("Generation"):
459
  with gr.Row():
460
  with gr.Column(scale=1):
461
+ sampler = gr.Dropdown(value="DPM++ 2M Karras", show_label=True, label="Sampling Method",
462
+ choices=samplers)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
463
 
464
  with gr.Column(scale=1):
465
  steps = gr.Slider(label="Sampling Steps", minimum=1, maximum=30, value=25, step=1)
466
 
467
  with gr.Row():
468
+ with gr.Column(scale=8):
469
  width = gr.Slider(label="Width", maximum=1024, value=512, step=8)
470
  height = gr.Slider(label="Height", maximum=1024, value=512, step=8)
471
 
472
  with gr.Column(scale=1):
473
+ batch_size = gr.Slider(label="Batch Size", maximum=1, value=1)
474
+ batch_count = gr.Slider(label="Batch Count", minimum=1, maximum=4, value=1, step=1)
475
 
476
  cfg_scale = gr.Slider(label="CFG Scale", minimum=1, maximum=20, value=7, step=1)
477
  seed = gr.Number(label="Seed", value=-1)
478
 
479
  with gr.Tab("Lora"):
 
480
  with gr.Row():
481
+ for lora in lora_list:
482
  lora_btn = gr.Button(lora, size="sm")
483
  lora_btn.click(place_lora, inputs=[prompt, lora_btn], outputs=prompt)
484
 
485
+ with gr.Column():
486
+ image_output = gr.Gallery(columns=3,
487
+ value=["https://images.prodia.xyz/8ede1a7c-c0ee-4ded-987d-6ffed35fc477.png"])
488
+
489
+ with gr.Tab("img2img", id='i2i'):
490
+ with gr.Row():
491
+ with gr.Column(scale=6, min_width=600):
492
+ i2i_prompt = gr.Textbox("space warrior, beautiful, female, ultrarealistic, soft lighting, 8k",
493
+ placeholder="Prompt", show_label=False, lines=3)
494
+ i2i_negative_prompt = gr.Textbox(placeholder="Negative Prompt", show_label=False, lines=3,
495
+ value="3d, cartoon, anime, (deformed eyes, nose, ears, nose), bad anatomy, ugly")
496
+ with gr.Row():
497
+ i2i_text_button = gr.Button("Generate", variant='primary', elem_id="generate")
498
+ i2i_stop_btn = gr.Button("Cancel", variant="stop", elem_id="generate", visible=False)
499
+
500
+ with gr.Row():
501
+ with gr.Column(scale=1):
502
+ with gr.Tab("Generation"):
503
+ i2i_image_input = gr.Image(type="pil")
504
+
505
+ with gr.Row():
506
+ with gr.Column(scale=1):
507
+ i2i_sampler = gr.Dropdown(value="DPM++ 2M Karras", show_label=True,
508
+ label="Sampling Method", choices=samplers)
509
+
510
+ with gr.Column(scale=1):
511
+ i2i_steps = gr.Slider(label="Sampling Steps", minimum=1, maximum=30, value=25, step=1)
512
+
513
+ with gr.Row():
514
+ with gr.Column(scale=6):
515
+ i2i_width = gr.Slider(label="Width", maximum=1024, value=512, step=8)
516
+ i2i_height = gr.Slider(label="Height", maximum=1024, value=512, step=8)
517
+
518
+ with gr.Column(scale=1):
519
+ i2i_batch_size = gr.Slider(label="Batch Size", maximum=1, value=1)
520
+ i2i_batch_count = gr.Slider(label="Batch Count", minimum=1, maximum=4, value=1, step=1)
521
+
522
+ i2i_cfg_scale = gr.Slider(label="CFG Scale", minimum=1, maximum=20, value=7, step=1)
523
+ i2i_denoising = gr.Slider(label="Denoising Strength", minimum=0, maximum=1, value=0.7, step=0.1)
524
+ i2i_seed = gr.Number(label="Seed", value=-1)
525
+
526
+ with gr.Tab("Lora"):
527
+ with gr.Row():
528
+ for lora in lora_list:
529
+ lora_btn = gr.Button(lora, size="sm")
530
+ lora_btn.click(place_lora, inputs=[i2i_prompt, lora_btn], outputs=i2i_prompt)
531
+
532
+ with gr.Column(scale=1):
533
+ i2i_image_output = gr.Gallery(columns=3,
534
+ value=["https://images.prodia.xyz/8ede1a7c-c0ee-4ded-987d-6ffed35fc477.png"])
535
+
536
+ with gr.Tab("Extras"):
537
+ with gr.Row():
538
+ with gr.Tab("Single Image"):
539
+ with gr.Column():
540
+ upscale_image_input = gr.Image(type="pil")
541
+ upscale_btn = gr.Button("Generate", variant="primary")
542
+ upscale_stop = gr.Button("Stop", variant="stop", visible=False)
543
+ with gr.Tab("Scale by"):
544
+ scale_by = gr.Radio([2, 4], value=2, label="Resize")
545
+
546
+ upscale_output = gr.Image()
547
 
548
  with gr.Tab("PNG Info"):
549
  def plaintext_to_html(text, classname=None):
 
570
 
571
  return info
572
 
573
+
574
  with gr.Row():
575
  with gr.Column():
576
  image_input = gr.Image(type="pil")
 
580
  send_to_txt2img_btn = gr.Button("Send to txt2img")
581
 
582
  with gr.Tab("Gallery"):
583
+ gallery_obj = gr.Gallery(height=1000, columns=6)
584
+
585
+ t2i_event = text_button.click(txt2img,
586
+ inputs=[prompt, negative_prompt, model, steps, sampler, cfg_scale, width, height,
587
+ seed, batch_count, gallery_obj], outputs=[image_output, gallery_obj, text_button, stop_btn])
588
+ stop_btn.click(fn=stop_t2i, outputs=[text_button, stop_btn], cancels=[t2i_event])
589
 
 
 
 
 
590
  image_input.upload(get_exif_data, inputs=[image_input], outputs=exif_output)
591
  send_to_txt2img_btn.click(send_to_txt2img, inputs=[image_input],
592
+ outputs=[tabs, prompt, negative_prompt, steps, seed, model, sampler, width, height,
593
+ cfg_scale])
594
+
595
+ i2i_event = i2i_text_button.click(img2img,
596
+ inputs=[i2i_image_input, i2i_denoising, i2i_prompt, i2i_negative_prompt,
597
+ model, i2i_steps, i2i_sampler, i2i_cfg_scale, i2i_width, i2i_height,
598
+ i2i_seed, i2i_batch_count, gallery_obj],
599
+ outputs=[i2i_image_output, gallery_obj, i2i_text_button, i2i_stop_btn])
600
+ i2i_stop_btn.click(fn=stop_i2i, outputs=[i2i_text_button, i2i_stop_btn], cancels=[i2i_event])
601
+
602
+ upscale_event = upscale_btn.click(fn=upscale_fn, inputs=[upscale_image_input, scale_by], outputs=[upscale_output, upscale_btn, upscale_stop])
603
+ upscale_stop.click(fn=stop_upscale, outputs=[upscale_btn, upscale_stop], cancels=[upscale_event])
604
 
605
+ demo.queue(concurrency_count=64, max_size=80, api_open=False).launch(max_threads=256)