2022-09-03 12:08:45 +03:00
import base64
import html
import io
import json
2022-09-10 11:10:00 +03:00
import math
2022-09-03 12:08:45 +03:00
import mimetypes
import os
2022-09-05 23:08:06 +03:00
import random
2022-09-03 12:08:45 +03:00
import sys
import time
import traceback
2022-09-06 19:33:51 +03:00
import numpy as np
import torch
2022-09-03 12:08:45 +03:00
from PIL import Image
import gradio as gr
import gradio . utils
2022-09-03 17:21:15 +03:00
import gradio . routes
2022-09-03 12:08:45 +03:00
from modules . paths import script_path
from modules . shared import opts , cmd_opts
import modules . shared as shared
from modules . sd_samplers import samplers , samplers_for_img2img
import modules . realesrgan_model as realesrgan
2022-09-03 17:21:15 +03:00
import modules . scripts
2022-09-07 13:35:02 +03:00
import modules . gfpgan_model
import modules . codeformer_model
2022-09-09 23:16:02 +03:00
import modules . styles
2022-09-03 12:08:45 +03:00
# this is a fix for Windows users. Without it, javascript files will be served with text/html content-type and the bowser will not show any UI
mimetypes . init ( )
mimetypes . add_type ( ' application/javascript ' , ' .js ' )
2022-09-05 19:37:11 +03:00
if not cmd_opts . share and not cmd_opts . listen :
2022-09-03 12:08:45 +03:00
# fix gradio phoning home
gradio . utils . version_check = lambda : None
gradio . utils . get_local_ip_address = lambda : ' 127.0.0.1 '
def gr_show ( visible = True ) :
return { " visible " : visible , " __type__ " : " update " }
sample_img2img = " assets/stable-samples/img2img/sketch-mountains-input.jpg "
sample_img2img = sample_img2img if os . path . exists ( sample_img2img ) else None
css_hide_progressbar = """
. wrap . m - 12 svg { display : none ! important ; }
. wrap . m - 12 : : before { content : " Loading... " }
. progress - bar { display : none ! important ; }
. meta - text { display : none ! important ; }
"""
def plaintext_to_html ( text ) :
2022-09-10 14:53:38 +03:00
text = " <p> " + " <br> \n " . join ( [ f " { html . escape ( x ) } " for x in text . split ( ' \n ' ) ] ) + " </p> "
2022-09-03 12:08:45 +03:00
return text
def image_from_url_text ( filedata ) :
if type ( filedata ) == list :
if len ( filedata ) == 0 :
return None
filedata = filedata [ 0 ]
if filedata . startswith ( " data:image/png;base64, " ) :
filedata = filedata [ len ( " data:image/png;base64, " ) : ]
filedata = base64 . decodebytes ( filedata . encode ( ' utf-8 ' ) )
image = Image . open ( io . BytesIO ( filedata ) )
return image
def send_gradio_gallery_to_image ( x ) :
if len ( x ) == 0 :
return None
return image_from_url_text ( x [ 0 ] )
2022-09-14 05:15:37 +03:00
2022-09-14 05:11:46 +03:00
def save_files ( js_data , images , index ) :
2022-09-03 12:08:45 +03:00
import csv
os . makedirs ( opts . outdir_save , exist_ok = True )
filenames = [ ]
data = json . loads ( js_data )
2022-09-14 05:11:46 +03:00
2022-09-14 06:01:30 +03:00
if index > - 1 and opts . save_selected_only and ( index > 0 or not opts . return_grid ) : # ensures we are looking at a specific non-grid picture, and we have save_selected_only
2022-09-14 05:11:46 +03:00
images = [ images [ index ] ]
data [ " seed " ] + = ( index - 1 if opts . return_grid else index )
2022-09-03 12:08:45 +03:00
2022-09-03 21:33:47 +03:00
with open ( os . path . join ( opts . outdir_save , " log.csv " ) , " a " , encoding = " utf8 " , newline = ' ' ) as file :
2022-09-03 12:08:45 +03:00
at_start = file . tell ( ) == 0
writer = csv . writer ( file )
if at_start :
2022-09-12 19:57:31 +03:00
writer . writerow ( [ " prompt " , " seed " , " width " , " height " , " sampler " , " cfgs " , " steps " , " filename " , " negative_prompt " ] )
2022-09-03 12:08:45 +03:00
filename_base = str ( int ( time . time ( ) * 1000 ) )
for i , filedata in enumerate ( images ) :
filename = filename_base + ( " " if len ( images ) == 1 else " - " + str ( i + 1 ) ) + " .png "
filepath = os . path . join ( opts . outdir_save , filename )
if filedata . startswith ( " data:image/png;base64, " ) :
filedata = filedata [ len ( " data:image/png;base64, " ) : ]
with open ( filepath , " wb " ) as imgfile :
imgfile . write ( base64 . decodebytes ( filedata . encode ( ' utf-8 ' ) ) )
filenames . append ( filename )
2022-09-12 19:57:31 +03:00
writer . writerow ( [ data [ " prompt " ] , data [ " seed " ] , data [ " width " ] , data [ " height " ] , data [ " sampler " ] , data [ " cfg_scale " ] , data [ " steps " ] , filenames [ 0 ] , data [ " negative_prompt " ] ] )
2022-09-03 12:08:45 +03:00
return ' ' , ' ' , plaintext_to_html ( f " Saved: { filenames [ 0 ] } " )
def wrap_gradio_call ( func ) :
def f ( * args , * * kwargs ) :
2022-09-17 07:49:31 +03:00
shared . mem_mon . monitor ( )
2022-09-03 12:08:45 +03:00
t = time . perf_counter ( )
try :
res = list ( func ( * args , * * kwargs ) )
except Exception as e :
print ( " Error completing request " , file = sys . stderr )
print ( " Arguments: " , args , kwargs , file = sys . stderr )
print ( traceback . format_exc ( ) , file = sys . stderr )
2022-09-06 19:33:51 +03:00
shared . state . job = " "
shared . state . job_count = 0
2022-09-03 12:08:45 +03:00
res = [ None , ' ' , f " <div class= ' error ' > { plaintext_to_html ( type ( e ) . __name__ + ' : ' + str ( e ) ) } </div> " ]
elapsed = time . perf_counter ( ) - t
2022-09-17 09:23:31 +03:00
mem_stats = { k : - ( v / / - ( 1024 * 1024 ) ) for k , v in shared . mem_mon . stop ( ) . items ( ) }
2022-09-17 07:49:31 +03:00
active_peak = mem_stats [ ' active_peak ' ]
reserved_peak = mem_stats [ ' reserved_peak ' ]
sys_peak = ' ? ' if opts . memmon_poll_rate < = 0 else mem_stats [ ' system_peak ' ]
sys_total = mem_stats [ ' total ' ]
sys_pct = ' ? ' if opts . memmon_poll_rate < = 0 else round ( sys_peak / sys_total * 100 , 2 )
vram_tooltip = " Torch active: Peak amount of VRAM used by Torch during generation, excluding cached data.
 " \
" Torch reserved: Peak amount of VRAM allocated by Torch, including all active and cached data.
 " \
" Sys VRAM: Peak amount of VRAM allocation across all applications / total GPU VRAM (peak utilization % ). "
2022-09-17 09:23:31 +03:00
vram_html = ' ' if opts . memmon_poll_rate == 0 else f " <p class= ' vram ' title= ' { vram_tooltip } ' >Torch active/reserved: { active_peak } / { reserved_peak } MiB, <wbr>Sys VRAM: { sys_peak } / { sys_total } MiB ( { sys_pct } %)</p> "
2022-09-03 12:08:45 +03:00
# last item is always HTML
2022-09-17 09:23:31 +03:00
res [ - 1 ] + = f " <div class= ' performance ' ><p class= ' time ' >Time taken: <wbr> { elapsed : .2f } s</p> { vram_html } </div> "
2022-09-03 12:08:45 +03:00
shared . state . interrupted = False
return tuple ( res )
return f
2022-09-06 02:09:01 +03:00
def check_progress_call ( ) :
if shared . state . job_count == 0 :
2022-09-06 19:33:51 +03:00
return " " , gr_show ( False ) , gr_show ( False )
2022-09-06 02:09:01 +03:00
2022-09-06 10:11:25 +03:00
progress = 0
if shared . state . job_count > 0 :
progress + = shared . state . job_no / shared . state . job_count
2022-09-06 02:09:01 +03:00
if shared . state . sampling_steps > 0 :
progress + = 1 / shared . state . job_count * shared . state . sampling_step / shared . state . sampling_steps
progress = min ( progress , 1 )
2022-09-06 19:33:51 +03:00
progressbar = " "
if opts . show_progressbar :
progressbar = f """ <div class= ' progressDiv ' ><div class= ' progress ' style= " width: { progress * 100 } % " > { str ( int ( progress * 100 ) ) + " % " if progress > 0.01 else " " } </div></div> """
image = gr_show ( False )
preview_visibility = gr_show ( False )
if opts . show_progress_every_n_steps > 0 :
2022-09-06 23:10:12 +03:00
if shared . parallel_processing_allowed :
2022-09-06 19:33:51 +03:00
2022-09-06 23:10:12 +03:00
if shared . state . sampling_step - shared . state . current_image_sampling_step > = opts . show_progress_every_n_steps and shared . state . current_latent is not None :
shared . state . current_image = modules . sd_samplers . sample_to_image ( shared . state . current_latent )
shared . state . current_image_sampling_step = shared . state . sampling_step
2022-09-06 20:26:09 +03:00
2022-09-06 19:33:51 +03:00
image = shared . state . current_image
if image is None or progress > = 1 :
image = gr . update ( value = None )
else :
preview_visibility = gr_show ( True )
2022-09-06 02:09:01 +03:00
2022-09-06 19:33:51 +03:00
return f " <span style= ' display: none ' > { time . time ( ) } </span><p> { progressbar } </p> " , preview_visibility , image
2022-09-06 02:09:01 +03:00
2022-09-05 23:08:06 +03:00
def roll_artist ( prompt ) :
allowed_cats = set ( [ x for x in shared . artist_db . categories ( ) if len ( opts . random_artist_categories ) == 0 or x in opts . random_artist_categories ] )
artist = random . choice ( [ x for x in shared . artist_db . artists if x . category in allowed_cats ] )
return prompt + " , " + artist . name if prompt != ' ' else artist . name
2022-09-04 13:52:01 +03:00
def visit ( x , func , path = " " ) :
if hasattr ( x , ' children ' ) :
for c in x . children :
visit ( c , func , path )
elif x . label is not None :
func ( path + " / " + str ( x . label ) , x )
2022-09-03 12:08:45 +03:00
2022-09-09 17:54:04 +03:00
def create_seed_inputs ( ) :
with gr . Row ( ) :
seed = gr . Number ( label = ' Seed ' , value = - 1 )
subseed = gr . Number ( label = ' Variation seed ' , value = - 1 , visible = False )
seed_checkbox = gr . Checkbox ( label = " Extra " , elem_id = " subseed_show " , value = False )
with gr . Row ( ) :
subseed_strength = gr . Slider ( label = ' Variation strength ' , value = 0.0 , minimum = 0 , maximum = 1 , step = 0.01 , visible = False )
seed_resize_from_w = gr . Slider ( minimum = 0 , maximum = 2048 , step = 64 , label = " Resize seed from width " , value = 0 , visible = False )
2022-09-12 22:41:59 +03:00
seed_resize_from_h = gr . Slider ( minimum = 0 , maximum = 2048 , step = 64 , label = " Resize seed from height " , value = 0 , visible = False )
2022-09-09 17:54:04 +03:00
def change_visiblity ( show ) :
return {
subseed : gr_show ( show ) ,
subseed_strength : gr_show ( show ) ,
seed_resize_from_h : gr_show ( show ) ,
seed_resize_from_w : gr_show ( show ) ,
}
seed_checkbox . change (
change_visiblity ,
inputs = [ seed_checkbox ] ,
outputs = [
subseed ,
subseed_strength ,
seed_resize_from_h ,
seed_resize_from_w
]
)
return seed , subseed , subseed_strength , seed_resize_from_h , seed_resize_from_w
2022-09-11 17:35:12 +03:00
def add_style ( name : str , prompt : str , negative_prompt : str ) :
if name is None :
2022-09-09 23:16:02 +03:00
return [ gr_show ( ) , gr_show ( ) ]
2022-09-11 17:35:12 +03:00
style = modules . styles . PromptStyle ( name , prompt , negative_prompt )
2022-09-14 17:56:21 +03:00
shared . prompt_styles . styles [ style . name ] = style
2022-09-11 17:35:12 +03:00
# Save all loaded prompt styles: this allows us to update the storage format in the future more easily, because we
# reserialize all styles every time we save them
2022-09-14 17:56:21 +03:00
shared . prompt_styles . save_styles ( shared . styles_filename )
2022-09-09 23:16:02 +03:00
2022-09-14 17:56:21 +03:00
update = { " visible " : True , " choices " : list ( shared . prompt_styles . styles ) , " __type__ " : " update " }
return [ update , update , update , update ]
def apply_styles ( prompt , prompt_neg , style1_name , style2_name ) :
prompt = shared . prompt_styles . apply_styles_to_prompt ( prompt , [ style1_name , style2_name ] )
prompt_neg = shared . prompt_styles . apply_negative_styles_to_prompt ( prompt_neg , [ style1_name , style2_name ] )
return [ gr . Textbox . update ( value = prompt ) , gr . Textbox . update ( value = prompt_neg ) , gr . Dropdown . update ( value = " None " ) , gr . Dropdown . update ( value = " None " ) ]
2022-09-09 23:16:02 +03:00
2022-09-11 18:48:36 +03:00
def interrogate ( image ) :
prompt = shared . interrogator . interrogate ( image )
return gr_show ( True ) if prompt is None else prompt
2022-09-14 17:56:21 +03:00
def create_toprow ( is_img2img ) :
with gr . Row ( elem_id = " toprow " ) :
with gr . Column ( scale = 4 ) :
with gr . Row ( ) :
with gr . Column ( scale = 8 ) :
with gr . Row ( ) :
prompt = gr . Textbox ( label = " Prompt " , elem_id = " prompt " , show_label = False , placeholder = " Prompt " , lines = 2 )
roll = gr . Button ( ' Roll ' , elem_id = " roll " , visible = len ( shared . artist_db . artists ) > 0 )
with gr . Column ( scale = 1 , elem_id = " style_pos_col " ) :
prompt_style = gr . Dropdown ( label = " Style 1 " , elem_id = " style_index " , choices = [ k for k , v in shared . prompt_styles . styles . items ( ) ] , value = next ( iter ( shared . prompt_styles . styles . keys ( ) ) ) , visible = len ( shared . prompt_styles . styles ) > 1 )
with gr . Row ( ) :
with gr . Column ( scale = 8 ) :
negative_prompt = gr . Textbox ( label = " Negative prompt " , elem_id = " negative_prompt " , show_label = False , placeholder = " Negative prompt " , lines = 2 )
with gr . Column ( scale = 1 , elem_id = " style_neg_col " ) :
prompt_style2 = gr . Dropdown ( label = " Style 2 " , elem_id = " style2_index " , choices = [ k for k , v in shared . prompt_styles . styles . items ( ) ] , value = next ( iter ( shared . prompt_styles . styles . keys ( ) ) ) , visible = len ( shared . prompt_styles . styles ) > 1 )
with gr . Column ( scale = 1 ) :
with gr . Row ( ) :
submit = gr . Button ( ' Generate ' , elem_id = " generate " , variant = ' primary ' )
with gr . Row ( ) :
if is_img2img :
interrogate = gr . Button ( ' Interrogate ' , elem_id = " interrogate " )
else :
interrogate = None
prompt_style_apply = gr . Button ( ' Apply style ' , elem_id = " style_apply " )
save_style = gr . Button ( ' Create style ' , elem_id = " style_create " )
check_progress = gr . Button ( ' Check progress ' , elem_id = " check_progress " , visible = False )
return prompt , roll , prompt_style , negative_prompt , prompt_style2 , submit , interrogate , prompt_style_apply , save_style , check_progress
2022-09-04 13:52:01 +03:00
def create_ui ( txt2img , img2img , run_extras , run_pnginfo ) :
2022-09-03 12:08:45 +03:00
with gr . Blocks ( analytics_enabled = False ) as txt2img_interface :
2022-09-14 17:56:21 +03:00
txt2img_prompt , roll , txt2img_prompt_style , txt2img_negative_prompt , txt2img_prompt_style2 , submit , _ , txt2img_prompt_style_apply , txt2img_save_style , check_progress = create_toprow ( is_img2img = False )
2022-09-03 12:08:45 +03:00
with gr . Row ( ) . style ( equal_height = False ) :
with gr . Column ( variant = ' panel ' ) :
steps = gr . Slider ( minimum = 1 , maximum = 150 , step = 1 , label = " Sampling Steps " , value = 20 )
sampler_index = gr . Radio ( label = ' Sampling method ' , elem_id = " txt2img_sampling " , choices = [ x . name for x in samplers ] , value = samplers [ 0 ] . name , type = " index " )
with gr . Row ( ) :
2022-09-07 12:32:28 +03:00
restore_faces = gr . Checkbox ( label = ' Restore faces ' , value = False , visible = len ( shared . face_restorers ) > 1 )
2022-09-05 03:25:37 +03:00
tiling = gr . Checkbox ( label = ' Tiling ' , value = False )
2022-09-03 12:08:45 +03:00
with gr . Row ( ) :
batch_count = gr . Slider ( minimum = 1 , maximum = cmd_opts . max_batch_count , step = 1 , label = ' Batch count ' , value = 1 )
batch_size = gr . Slider ( minimum = 1 , maximum = 8 , step = 1 , label = ' Batch size ' , value = 1 )
2022-09-12 11:55:27 +03:00
cfg_scale = gr . Slider ( minimum = 1.0 , maximum = 30.0 , step = 0.5 , label = ' CFG Scale ' , value = 7.0 )
2022-09-03 12:08:45 +03:00
with gr . Group ( ) :
width = gr . Slider ( minimum = 64 , maximum = 2048 , step = 64 , label = " Width " , value = 512 )
2022-09-12 22:41:59 +03:00
height = gr . Slider ( minimum = 64 , maximum = 2048 , step = 64 , label = " Height " , value = 512 )
2022-09-03 12:08:45 +03:00
2022-09-09 17:54:04 +03:00
seed , subseed , subseed_strength , seed_resize_from_h , seed_resize_from_w = create_seed_inputs ( )
2022-09-03 12:08:45 +03:00
2022-09-03 17:21:15 +03:00
with gr . Group ( ) :
2022-09-04 01:29:43 +03:00
custom_inputs = modules . scripts . scripts_txt2img . setup_ui ( is_img2img = False )
2022-09-03 12:08:45 +03:00
with gr . Column ( variant = ' panel ' ) :
2022-09-17 12:38:15 +03:00
progressbar = gr . HTML ( elem_id = " progressbar " )
2022-09-03 12:08:45 +03:00
with gr . Group ( ) :
2022-09-06 19:33:51 +03:00
txt2img_preview = gr . Image ( elem_id = ' txt2img_preview ' , visible = False )
2022-09-08 15:08:23 +03:00
txt2img_gallery = gr . Gallery ( label = ' Output ' , elem_id = ' txt2img_gallery ' ) . style ( grid = 4 )
2022-09-03 12:08:45 +03:00
with gr . Group ( ) :
with gr . Row ( ) :
save = gr . Button ( ' Save ' )
send_to_img2img = gr . Button ( ' Send to img2img ' )
send_to_inpaint = gr . Button ( ' Send to inpaint ' )
send_to_extras = gr . Button ( ' Send to extras ' )
interrupt = gr . Button ( ' Interrupt ' )
with gr . Group ( ) :
html_info = gr . HTML ( )
generation_info = gr . Textbox ( visible = False )
txt2img_args = dict (
fn = txt2img ,
2022-09-06 02:09:01 +03:00
_js = " submit " ,
2022-09-03 12:08:45 +03:00
inputs = [
2022-09-09 23:16:02 +03:00
txt2img_prompt ,
2022-09-11 17:35:12 +03:00
txt2img_negative_prompt ,
2022-09-09 23:16:02 +03:00
txt2img_prompt_style ,
2022-09-14 17:56:21 +03:00
txt2img_prompt_style2 ,
2022-09-03 12:08:45 +03:00
steps ,
sampler_index ,
2022-09-07 12:32:28 +03:00
restore_faces ,
2022-09-05 03:25:37 +03:00
tiling ,
2022-09-03 12:08:45 +03:00
batch_count ,
batch_size ,
cfg_scale ,
seed ,
2022-09-09 17:54:04 +03:00
subseed , subseed_strength , seed_resize_from_h , seed_resize_from_w ,
2022-09-03 12:08:45 +03:00
height ,
width ,
2022-09-03 17:21:15 +03:00
] + custom_inputs ,
2022-09-03 12:08:45 +03:00
outputs = [
txt2img_gallery ,
generation_info ,
html_info
]
)
2022-09-09 23:16:02 +03:00
txt2img_prompt . submit ( * * txt2img_args )
2022-09-03 12:08:45 +03:00
submit . click ( * * txt2img_args )
2022-09-06 02:09:01 +03:00
check_progress . click (
fn = check_progress_call ,
2022-09-06 19:33:51 +03:00
show_progress = False ,
2022-09-06 02:09:01 +03:00
inputs = [ ] ,
2022-09-06 19:33:51 +03:00
outputs = [ progressbar , txt2img_preview , txt2img_preview ] ,
2022-09-06 02:09:01 +03:00
)
2022-09-03 12:08:45 +03:00
interrupt . click (
fn = lambda : shared . state . interrupt ( ) ,
inputs = [ ] ,
outputs = [ ] ,
)
save . click (
fn = wrap_gradio_call ( save_files ) ,
2022-09-14 05:11:46 +03:00
_js = " (x, y, z) => [x, y, selected_gallery_index()] " ,
2022-09-03 12:08:45 +03:00
inputs = [
generation_info ,
txt2img_gallery ,
2022-09-14 05:11:46 +03:00
html_info
2022-09-03 12:08:45 +03:00
] ,
outputs = [
html_info ,
html_info ,
html_info ,
]
)
2022-09-05 23:08:06 +03:00
roll . click (
fn = roll_artist ,
inputs = [
2022-09-09 23:16:02 +03:00
txt2img_prompt ,
2022-09-05 23:08:06 +03:00
] ,
outputs = [
2022-09-09 23:16:02 +03:00
txt2img_prompt ,
2022-09-05 23:08:06 +03:00
]
)
2022-09-03 12:08:45 +03:00
with gr . Blocks ( analytics_enabled = False ) as img2img_interface :
2022-09-14 17:56:21 +03:00
img2img_prompt , roll , img2img_prompt_style , img2img_negative_prompt , img2img_prompt_style2 , submit , img2img_interrogate , img2img_prompt_style_apply , img2img_save_style , check_progress = create_toprow ( is_img2img = True )
2022-09-03 12:08:45 +03:00
with gr . Row ( ) . style ( equal_height = False ) :
with gr . Column ( variant = ' panel ' ) :
with gr . Group ( ) :
2022-09-14 14:47:54 +03:00
switch_mode = gr . Radio ( label = ' Mode ' , elem_id = " img2img_mode " , choices = [ ' Redraw whole image ' , ' Inpaint a part of image ' , ' SD upscale ' ] , value = ' Redraw whole image ' , type = " index " , show_label = False )
2022-09-03 12:08:45 +03:00
init_img = gr . Image ( label = " Image for img2img " , source = " upload " , interactive = True , type = " pil " )
2022-09-07 23:37:54 +03:00
init_img_with_mask = gr . Image ( label = " Image for inpainting with mask " , elem_id = " img2maskimg " , source = " upload " , interactive = True , type = " pil " , tool = " sketch " , visible = False , image_mode = " RGBA " )
2022-09-09 19:43:16 +03:00
init_mask = gr . Image ( label = " Mask " , source = " upload " , interactive = True , type = " pil " , visible = False )
2022-09-12 18:40:06 +03:00
init_img_with_mask_comment = gr . HTML ( elem_id = " mask_bug_info " , value = " <small>if the editor shows ERROR, switch to another tab and back, then to another img2img mode above and back</small> " , visible = False )
2022-09-09 19:43:16 +03:00
with gr . Row ( ) :
resize_mode = gr . Radio ( label = " Resize mode " , elem_id = " resize_mode " , show_label = False , choices = [ " Just resize " , " Crop and resize " , " Resize and fill " ] , type = " index " , value = " Just resize " )
mask_mode = gr . Radio ( label = " Mask mode " , show_label = False , choices = [ " Draw mask " , " Upload mask " ] , type = " index " , value = " Draw mask " )
2022-09-03 12:08:45 +03:00
steps = gr . Slider ( minimum = 1 , maximum = 150 , step = 1 , label = " Sampling Steps " , value = 20 )
sampler_index = gr . Radio ( label = ' Sampling method ' , choices = [ x . name for x in samplers_for_img2img ] , value = samplers_for_img2img [ 0 ] . name , type = " index " )
mask_blur = gr . Slider ( label = ' Mask blur ' , minimum = 0 , maximum = 64 , step = 1 , value = 4 , visible = False )
2022-09-03 21:02:38 +03:00
inpainting_fill = gr . Radio ( label = ' Masked content ' , choices = [ ' fill ' , ' original ' , ' latent noise ' , ' latent nothing ' ] , value = ' fill ' , type = " index " , visible = False )
2022-09-03 12:08:45 +03:00
with gr . Row ( ) :
2022-09-04 01:29:43 +03:00
inpaint_full_res = gr . Checkbox ( label = ' Inpaint at full resolution ' , value = False , visible = False )
2022-09-03 21:02:38 +03:00
inpainting_mask_invert = gr . Radio ( label = ' Masking mode ' , choices = [ ' Inpaint masked ' , ' Inpaint not masked ' ] , value = ' Inpaint masked ' , type = " index " , visible = False )
with gr . Row ( ) :
2022-09-07 12:32:28 +03:00
restore_faces = gr . Checkbox ( label = ' Restore faces ' , value = False , visible = len ( shared . face_restorers ) > 1 )
2022-09-05 03:25:37 +03:00
tiling = gr . Checkbox ( label = ' Tiling ' , value = False )
2022-09-04 18:54:12 +03:00
sd_upscale_overlap = gr . Slider ( minimum = 0 , maximum = 256 , step = 16 , label = ' Tile overlap ' , value = 64 , visible = False )
2022-09-03 12:08:45 +03:00
with gr . Row ( ) :
2022-09-04 18:54:12 +03:00
sd_upscale_upscaler_name = gr . Radio ( label = ' Upscaler ' , choices = [ x . name for x in shared . sd_upscalers ] , value = shared . sd_upscalers [ 0 ] . name , type = " index " , visible = False )
2022-09-03 12:08:45 +03:00
with gr . Row ( ) :
batch_count = gr . Slider ( minimum = 1 , maximum = cmd_opts . max_batch_count , step = 1 , label = ' Batch count ' , value = 1 )
batch_size = gr . Slider ( minimum = 1 , maximum = 8 , step = 1 , label = ' Batch size ' , value = 1 )
with gr . Group ( ) :
2022-09-12 11:55:27 +03:00
cfg_scale = gr . Slider ( minimum = 1.0 , maximum = 30.0 , step = 0.5 , label = ' CFG Scale ' , value = 7.0 )
2022-09-08 15:02:06 +03:00
denoising_strength = gr . Slider ( minimum = 0.0 , maximum = 1.0 , step = 0.01 , label = ' Denoising strength ' , value = 0.75 )
2022-09-03 12:08:45 +03:00
with gr . Group ( ) :
width = gr . Slider ( minimum = 64 , maximum = 2048 , step = 64 , label = " Width " , value = 512 )
2022-09-12 22:41:59 +03:00
height = gr . Slider ( minimum = 64 , maximum = 2048 , step = 64 , label = " Height " , value = 512 )
2022-09-03 12:08:45 +03:00
2022-09-09 17:54:04 +03:00
seed , subseed , subseed_strength , seed_resize_from_h , seed_resize_from_w = create_seed_inputs ( )
2022-09-03 12:08:45 +03:00
2022-09-03 17:21:15 +03:00
with gr . Group ( ) :
2022-09-04 01:29:43 +03:00
custom_inputs = modules . scripts . scripts_img2img . setup_ui ( is_img2img = True )
2022-09-03 17:21:15 +03:00
2022-09-03 12:08:45 +03:00
with gr . Column ( variant = ' panel ' ) :
2022-09-17 12:38:15 +03:00
progressbar = gr . HTML ( elem_id = " progressbar " )
2022-09-03 12:08:45 +03:00
with gr . Group ( ) :
2022-09-06 19:33:51 +03:00
img2img_preview = gr . Image ( elem_id = ' img2img_preview ' , visible = False )
2022-09-08 15:08:23 +03:00
img2img_gallery = gr . Gallery ( label = ' Output ' , elem_id = ' img2img_gallery ' ) . style ( grid = 4 )
2022-09-03 12:08:45 +03:00
with gr . Group ( ) :
with gr . Row ( ) :
save = gr . Button ( ' Save ' )
2022-09-06 19:33:51 +03:00
img2img_send_to_img2img = gr . Button ( ' Send to img2img ' )
img2img_send_to_inpaint = gr . Button ( ' Send to inpaint ' )
2022-09-03 12:08:45 +03:00
img2img_send_to_extras = gr . Button ( ' Send to extras ' )
2022-09-06 19:33:51 +03:00
interrupt = gr . Button ( ' Interrupt ' )
2022-09-09 23:16:02 +03:00
img2img_save_style = gr . Button ( ' Save prompt as style ' )
2022-09-03 12:08:45 +03:00
2022-09-06 02:09:01 +03:00
2022-09-03 12:08:45 +03:00
with gr . Group ( ) :
html_info = gr . HTML ( )
generation_info = gr . Textbox ( visible = False )
2022-09-09 19:43:16 +03:00
def apply_mode ( mode , uploadmask ) :
2022-09-03 12:08:45 +03:00
is_classic = mode == 0
is_inpaint = mode == 1
2022-09-14 14:47:54 +03:00
is_upscale = mode == 2
2022-09-03 12:08:45 +03:00
return {
2022-09-09 19:43:16 +03:00
init_img : gr_show ( not is_inpaint or ( is_inpaint and uploadmask == 1 ) ) ,
init_img_with_mask : gr_show ( is_inpaint and uploadmask == 0 ) ,
2022-09-10 11:10:00 +03:00
init_img_with_mask_comment : gr_show ( is_inpaint and uploadmask == 0 ) ,
2022-09-09 19:43:16 +03:00
init_mask : gr_show ( is_inpaint and uploadmask == 1 ) ,
mask_mode : gr_show ( is_inpaint ) ,
2022-09-03 12:08:45 +03:00
mask_blur : gr_show ( is_inpaint ) ,
inpainting_fill : gr_show ( is_inpaint ) ,
sd_upscale_upscaler_name : gr_show ( is_upscale ) ,
2022-09-03 17:21:15 +03:00
sd_upscale_overlap : gr_show ( is_upscale ) ,
2022-09-03 12:08:45 +03:00
inpaint_full_res : gr_show ( is_inpaint ) ,
2022-09-03 21:02:38 +03:00
inpainting_mask_invert : gr_show ( is_inpaint ) ,
2022-09-11 18:48:36 +03:00
img2img_interrogate : gr_show ( not is_inpaint ) ,
2022-09-03 12:08:45 +03:00
}
switch_mode . change (
apply_mode ,
2022-09-09 19:43:16 +03:00
inputs = [ switch_mode , mask_mode ] ,
2022-09-03 12:08:45 +03:00
outputs = [
init_img ,
init_img_with_mask ,
2022-09-10 11:10:00 +03:00
init_img_with_mask_comment ,
2022-09-09 19:43:16 +03:00
init_mask ,
mask_mode ,
2022-09-03 12:08:45 +03:00
mask_blur ,
inpainting_fill ,
sd_upscale_upscaler_name ,
sd_upscale_overlap ,
inpaint_full_res ,
2022-09-03 21:02:38 +03:00
inpainting_mask_invert ,
2022-09-11 18:48:36 +03:00
img2img_interrogate ,
2022-09-03 12:08:45 +03:00
]
)
2022-09-09 19:43:16 +03:00
mask_mode . change (
lambda mode : {
init_img : gr_show ( mode == 1 ) ,
init_img_with_mask : gr_show ( mode == 0 ) ,
init_mask : gr_show ( mode == 1 ) ,
} ,
inputs = [ mask_mode ] ,
outputs = [
init_img ,
init_img_with_mask ,
init_mask ,
] ,
)
2022-09-03 12:08:45 +03:00
img2img_args = dict (
fn = img2img ,
2022-09-06 02:09:01 +03:00
_js = " submit " ,
2022-09-03 12:08:45 +03:00
inputs = [
2022-09-09 23:16:02 +03:00
img2img_prompt ,
2022-09-11 17:35:12 +03:00
img2img_negative_prompt ,
2022-09-09 23:16:02 +03:00
img2img_prompt_style ,
2022-09-14 17:56:21 +03:00
img2img_prompt_style2 ,
2022-09-03 12:08:45 +03:00
init_img ,
init_img_with_mask ,
2022-09-09 19:43:16 +03:00
init_mask ,
mask_mode ,
2022-09-03 12:08:45 +03:00
steps ,
sampler_index ,
mask_blur ,
inpainting_fill ,
2022-09-07 12:32:28 +03:00
restore_faces ,
2022-09-05 03:25:37 +03:00
tiling ,
2022-09-03 12:08:45 +03:00
switch_mode ,
batch_count ,
batch_size ,
cfg_scale ,
denoising_strength ,
seed ,
2022-09-09 17:54:04 +03:00
subseed , subseed_strength , seed_resize_from_h , seed_resize_from_w ,
2022-09-03 12:08:45 +03:00
height ,
width ,
resize_mode ,
sd_upscale_upscaler_name ,
sd_upscale_overlap ,
inpaint_full_res ,
2022-09-03 21:02:38 +03:00
inpainting_mask_invert ,
2022-09-03 17:21:15 +03:00
] + custom_inputs ,
2022-09-03 12:08:45 +03:00
outputs = [
img2img_gallery ,
generation_info ,
html_info
]
)
2022-09-09 23:16:02 +03:00
img2img_prompt . submit ( * * img2img_args )
2022-09-03 12:08:45 +03:00
submit . click ( * * img2img_args )
2022-09-11 18:48:36 +03:00
img2img_interrogate . click (
fn = interrogate ,
inputs = [ init_img ] ,
outputs = [ img2img_prompt ] ,
)
2022-09-06 02:09:01 +03:00
check_progress . click (
fn = check_progress_call ,
2022-09-06 19:33:51 +03:00
show_progress = False ,
2022-09-06 02:09:01 +03:00
inputs = [ ] ,
2022-09-06 19:33:51 +03:00
outputs = [ progressbar , img2img_preview , img2img_preview ] ,
2022-09-06 02:09:01 +03:00
)
2022-09-03 12:08:45 +03:00
interrupt . click (
fn = lambda : shared . state . interrupt ( ) ,
inputs = [ ] ,
outputs = [ ] ,
)
save . click (
fn = wrap_gradio_call ( save_files ) ,
2022-09-14 05:11:46 +03:00
_js = " (x, y, z) => [x, y, selected_gallery_index()] " ,
2022-09-03 12:08:45 +03:00
inputs = [
generation_info ,
img2img_gallery ,
2022-09-14 05:11:46 +03:00
html_info
2022-09-03 12:08:45 +03:00
] ,
outputs = [
html_info ,
html_info ,
html_info ,
]
)
2022-09-14 17:56:21 +03:00
roll . click (
fn = roll_artist ,
inputs = [
img2img_prompt ,
] ,
outputs = [
img2img_prompt ,
]
)
prompts = [ ( txt2img_prompt , txt2img_negative_prompt ) , ( img2img_prompt , img2img_negative_prompt ) ]
style_dropdowns = [ ( txt2img_prompt_style , txt2img_prompt_style2 ) , ( img2img_prompt_style , img2img_prompt_style2 ) ]
2022-09-11 17:35:12 +03:00
dummy_component = gr . Label ( visible = False )
2022-09-14 17:56:21 +03:00
for button , ( prompt , negative_prompt ) in zip ( [ txt2img_save_style , img2img_save_style ] , prompts ) :
2022-09-09 23:16:02 +03:00
button . click (
fn = add_style ,
_js = " ask_for_style_name " ,
2022-09-11 17:35:12 +03:00
# Have to pass empty dummy component here, because the JavaScript and Python function have to accept
# the same number of parameters, but we only know the style-name after the JavaScript prompt
inputs = [ dummy_component , prompt , negative_prompt ] ,
2022-09-14 17:56:21 +03:00
outputs = [ txt2img_prompt_style , img2img_prompt_style , txt2img_prompt_style2 , img2img_prompt_style2 ] ,
)
for button , ( prompt , negative_prompt ) , ( style1 , style2 ) in zip ( [ txt2img_prompt_style_apply , img2img_prompt_style_apply ] , prompts , style_dropdowns ) :
button . click (
fn = apply_styles ,
inputs = [ prompt , negative_prompt , style1 , style2 ] ,
outputs = [ prompt , negative_prompt , style1 , style2 ] ,
2022-09-09 23:16:02 +03:00
)
2022-09-03 12:08:45 +03:00
with gr . Blocks ( analytics_enabled = False ) as extras_interface :
with gr . Row ( ) . style ( equal_height = False ) :
with gr . Column ( variant = ' panel ' ) :
2022-09-16 06:23:37 +03:00
with gr . Tabs ( ) :
with gr . TabItem ( ' Single Image ' ) :
image = gr . Image ( label = " Source " , source = " upload " , interactive = True , type = " pil " )
with gr . TabItem ( ' Batch Process ' ) :
2022-09-16 10:21:59 +03:00
image_batch = gr . File ( label = " Batch Process " , file_count = " multiple " , interactive = True , type = " file " )
2022-09-04 18:54:12 +03:00
upscaling_resize = gr . Slider ( minimum = 1.0 , maximum = 4.0 , step = 0.05 , label = " Resize " , value = 2 )
with gr . Group ( ) :
extras_upscaler_1 = gr . Radio ( label = ' Upscaler 1 ' , choices = [ x . name for x in shared . sd_upscalers ] , value = shared . sd_upscalers [ 0 ] . name , type = " index " )
with gr . Group ( ) :
extras_upscaler_2 = gr . Radio ( label = ' Upscaler 2 ' , choices = [ x . name for x in shared . sd_upscalers ] , value = shared . sd_upscalers [ 0 ] . name , type = " index " )
extras_upscaler_2_visibility = gr . Slider ( minimum = 0.0 , maximum = 1.0 , step = 0.001 , label = " Upscaler 2 visibility " , value = 1 )
with gr . Group ( ) :
2022-09-07 13:35:02 +03:00
gfpgan_visibility = gr . Slider ( minimum = 0.0 , maximum = 1.0 , step = 0.001 , label = " GFPGAN visibility " , value = 0 , interactive = modules . gfpgan_model . have_gfpgan )
with gr . Group ( ) :
codeformer_visibility = gr . Slider ( minimum = 0.0 , maximum = 1.0 , step = 0.001 , label = " CodeFormer visibility " , value = 0 , interactive = modules . codeformer_model . have_codeformer )
2022-09-07 13:46:08 +03:00
codeformer_weight = gr . Slider ( minimum = 0.0 , maximum = 1.0 , step = 0.001 , label = " CodeFormer weight (0 = maximum effect, 1 = minimum effect) " , value = 0 , interactive = modules . codeformer_model . have_codeformer )
2022-09-03 12:08:45 +03:00
submit = gr . Button ( ' Generate ' , elem_id = " extras_generate " , variant = ' primary ' )
with gr . Column ( variant = ' panel ' ) :
2022-09-16 06:23:37 +03:00
result_images = gr . Gallery ( label = " Result " )
2022-09-03 12:08:45 +03:00
html_info_x = gr . HTML ( )
html_info = gr . HTML ( )
extras_args = dict (
fn = run_extras ,
inputs = [
image ,
2022-09-16 06:23:37 +03:00
image_batch ,
2022-09-07 13:35:02 +03:00
gfpgan_visibility ,
codeformer_visibility ,
codeformer_weight ,
2022-09-04 18:54:12 +03:00
upscaling_resize ,
extras_upscaler_1 ,
extras_upscaler_2 ,
extras_upscaler_2_visibility ,
2022-09-03 12:08:45 +03:00
] ,
outputs = [
2022-09-16 06:23:37 +03:00
result_images ,
2022-09-03 12:08:45 +03:00
html_info_x ,
html_info ,
]
)
submit . click ( * * extras_args )
pnginfo_interface = gr . Interface (
wrap_gradio_call ( run_pnginfo ) ,
inputs = [
gr . Image ( label = " Source " , source = " upload " , interactive = True , type = " pil " ) ,
] ,
outputs = [
gr . HTML ( ) ,
gr . HTML ( ) ,
gr . HTML ( ) ,
] ,
allow_flagging = " never " ,
analytics_enabled = False ,
)
def create_setting_component ( key ) :
def fun ( ) :
return opts . data [ key ] if key in opts . data else opts . data_labels [ key ] . default
info = opts . data_labels [ key ]
t = type ( info . default )
2022-09-11 23:00:42 +03:00
args = info . component_args ( ) if callable ( info . component_args ) else info . component_args
2022-09-03 12:08:45 +03:00
if info . component is not None :
2022-09-11 23:00:42 +03:00
comp = info . component
2022-09-03 12:08:45 +03:00
elif t == str :
2022-09-11 23:00:42 +03:00
comp = gr . Textbox
2022-09-03 12:08:45 +03:00
elif t == int :
2022-09-11 23:00:42 +03:00
comp = gr . Number
2022-09-03 12:08:45 +03:00
elif t == bool :
2022-09-11 23:00:42 +03:00
comp = gr . Checkbox
2022-09-03 12:08:45 +03:00
else :
raise Exception ( f ' bad options item type: { str ( t ) } for key { key } ' )
2022-09-11 23:00:42 +03:00
return comp ( label = info . label , value = fun , * * ( args or { } ) )
2022-09-03 12:08:45 +03:00
2022-09-10 11:10:00 +03:00
components = [ ]
keys = list ( opts . data_labels . keys ( ) )
settings_cols = 3
items_per_col = math . ceil ( len ( keys ) / settings_cols )
2022-09-03 12:08:45 +03:00
def run_settings ( * args ) :
up = [ ]
2022-09-10 11:10:00 +03:00
for key , value , comp in zip ( opts . data_labels . keys ( ) , args , components ) :
2022-09-11 23:00:42 +03:00
comp_args = opts . data_labels [ key ] . component_args
if comp_args and isinstance ( comp_args , dict ) and comp_args . get ( ' visible ' ) is False :
continue
2022-09-17 12:05:04 +03:00
oldval = opts . data . get ( key , None )
2022-09-03 12:08:45 +03:00
opts . data [ key ] = value
2022-09-17 12:05:04 +03:00
if oldval != value and opts . data_labels [ key ] . onchange is not None :
opts . data_labels [ key ] . onchange ( )
2022-09-03 12:08:45 +03:00
up . append ( comp . update ( value = value ) )
opts . save ( shared . config_filename )
2022-09-10 11:10:00 +03:00
return ' Settings applied. '
2022-09-03 12:08:45 +03:00
2022-09-10 11:10:00 +03:00
with gr . Blocks ( analytics_enabled = False ) as settings_interface :
submit = gr . Button ( value = " Apply settings " , variant = ' primary ' )
result = gr . HTML ( )
with gr . Row ( elem_id = " settings " ) . style ( equal_height = False ) :
for colno in range ( settings_cols ) :
with gr . Column ( variant = ' panel ' ) :
for rowno in range ( items_per_col ) :
index = rowno + colno * items_per_col
if index < len ( keys ) :
components . append ( create_setting_component ( keys [ index ] ) )
submit . click (
fn = run_settings ,
inputs = components ,
outputs = [ result ]
)
2022-09-03 12:08:45 +03:00
interfaces = [
2022-09-10 11:10:00 +03:00
( txt2img_interface , " txt2img " , " txt2img " ) ,
( img2img_interface , " img2img " , " img2img " ) ,
( extras_interface , " Extras " , " extras " ) ,
( pnginfo_interface , " PNG Info " , " pnginfo " ) ,
( settings_interface , " Settings " , " settings " ) ,
2022-09-03 12:08:45 +03:00
]
with open ( os . path . join ( script_path , " style.css " ) , " r " , encoding = " utf8 " ) as file :
css = file . read ( )
if not cmd_opts . no_progressbar_hiding :
css + = css_hide_progressbar
2022-09-10 11:10:00 +03:00
with gr . Blocks ( css = css , analytics_enabled = False , title = " Stable Diffusion " ) as demo :
with gr . Tabs ( ) as tabs :
for interface , label , ifid in interfaces :
with gr . TabItem ( label , id = ifid ) :
interface . render ( )
tabs . change (
fn = lambda x : x ,
inputs = [ init_img_with_mask ] ,
outputs = [ init_img_with_mask ] ,
)
send_to_img2img . click (
fn = lambda x : image_from_url_text ( x ) ,
2022-09-11 00:21:47 +03:00
_js = " extract_image_from_gallery_img2img " ,
2022-09-10 11:10:00 +03:00
inputs = [ txt2img_gallery ] ,
outputs = [ init_img ] ,
)
send_to_inpaint . click (
fn = lambda x : image_from_url_text ( x ) ,
2022-09-11 00:21:47 +03:00
_js = " extract_image_from_gallery_img2img " ,
2022-09-10 11:10:00 +03:00
inputs = [ txt2img_gallery ] ,
outputs = [ init_img_with_mask ] ,
)
img2img_send_to_img2img . click (
fn = lambda x : image_from_url_text ( x ) ,
_js = " extract_image_from_gallery " ,
inputs = [ img2img_gallery ] ,
outputs = [ init_img ] ,
)
img2img_send_to_inpaint . click (
fn = lambda x : image_from_url_text ( x ) ,
_js = " extract_image_from_gallery " ,
inputs = [ img2img_gallery ] ,
outputs = [ init_img_with_mask ] ,
)
send_to_extras . click (
fn = lambda x : image_from_url_text ( x ) ,
2022-09-11 00:21:47 +03:00
_js = " extract_image_from_gallery_extras " ,
2022-09-10 11:10:00 +03:00
inputs = [ txt2img_gallery ] ,
outputs = [ image ] ,
)
img2img_send_to_extras . click (
fn = lambda x : image_from_url_text ( x ) ,
2022-09-11 00:21:47 +03:00
_js = " extract_image_from_gallery_extras " ,
2022-09-10 11:10:00 +03:00
inputs = [ img2img_gallery ] ,
outputs = [ image ] ,
)
2022-09-03 12:08:45 +03:00
2022-09-10 08:18:54 +03:00
ui_config_file = cmd_opts . ui_config_file
2022-09-04 13:52:01 +03:00
ui_settings = { }
settings_count = len ( ui_settings )
error_loading = False
try :
if os . path . exists ( ui_config_file ) :
with open ( ui_config_file , " r " , encoding = " utf8 " ) as file :
ui_settings = json . load ( file )
except Exception :
error_loading = True
print ( " Error loading settings: " , file = sys . stderr )
print ( traceback . format_exc ( ) , file = sys . stderr )
def loadsave ( path , x ) :
2022-09-05 19:11:29 +03:00
def apply_field ( obj , field , condition = None ) :
2022-09-04 13:52:01 +03:00
key = path + " / " + field
saved_value = ui_settings . get ( key , None )
if saved_value is None :
ui_settings [ key ] = getattr ( obj , field )
2022-09-05 19:11:29 +03:00
elif condition is None or condition ( saved_value ) :
2022-09-04 13:52:01 +03:00
setattr ( obj , field , saved_value )
if type ( x ) == gr . Slider :
apply_field ( x , ' value ' )
apply_field ( x , ' minimum ' )
apply_field ( x , ' maximum ' )
apply_field ( x , ' step ' )
if type ( x ) == gr . Radio :
2022-09-05 19:11:29 +03:00
apply_field ( x , ' value ' , lambda val : val in x . choices )
2022-09-04 13:52:01 +03:00
visit ( txt2img_interface , loadsave , " txt2img " )
visit ( img2img_interface , loadsave , " img2img " )
2022-09-11 11:31:16 +03:00
visit ( extras_interface , loadsave , " extras " )
2022-09-04 13:52:01 +03:00
if not error_loading and ( not os . path . exists ( ui_config_file ) or settings_count != len ( ui_settings ) ) :
with open ( ui_config_file , " w " , encoding = " utf8 " ) as file :
json . dump ( ui_settings , file , indent = 4 )
2022-09-03 12:08:45 +03:00
return demo
2022-09-03 17:21:15 +03:00
with open ( os . path . join ( script_path , " script.js " ) , " r " , encoding = " utf8 " ) as jsfile :
javascript = jsfile . read ( )
2022-09-03 12:08:45 +03:00
2022-09-03 17:21:15 +03:00
def template_response ( * args , * * kwargs ) :
res = gradio_routes_templates_response ( * args , * * kwargs )
res . body = res . body . replace ( b ' </head> ' , f ' <script> { javascript } </script></head> ' . encode ( " utf8 " ) )
res . init_headers ( )
return res
2022-09-03 12:08:45 +03:00
2022-09-03 17:21:15 +03:00
gradio_routes_templates_response = gradio . routes . templates . TemplateResponse
gradio . routes . templates . TemplateResponse = template_response