2022-09-03 09:08:45 +00:00
import base64
import html
import io
import json
2022-09-10 08:10:00 +00:00
import math
2022-09-03 09:08:45 +00:00
import mimetypes
import os
2022-09-05 20:08:06 +00:00
import random
2022-09-03 09:08:45 +00:00
import sys
2022-10-15 10:11:28 +00:00
import tempfile
2022-09-03 09:08:45 +00:00
import time
import traceback
2022-09-28 08:31:53 +00:00
import platform
import subprocess as sp
2022-10-14 17:04:47 +00:00
from functools import partial , reduce
2022-09-03 09:08:45 +00:00
2022-09-06 16:33:51 +00:00
import numpy as np
import torch
2022-09-28 14:05:23 +00:00
from PIL import Image , PngImagePlugin
2022-09-29 14:54:45 +00:00
import piexif
2022-09-03 09:08:45 +00:00
import gradio as gr
import gradio . utils
2022-09-03 14:21:15 +00:00
import gradio . routes
2022-09-03 09:08:45 +00:00
2022-10-17 18:15:32 +00:00
from modules import sd_hijack , sd_models , localization
2022-09-03 09:08:45 +00:00
from modules . paths import script_path
2022-10-16 17:08:23 +00:00
from modules . shared import opts , cmd_opts , restricted_opts
2022-10-08 16:02:56 +00:00
if cmd_opts . deepdanbooru :
from modules . deepbooru import get_deepbooru_tags
2022-09-03 09:08:45 +00:00
import modules . shared as shared
from modules . sd_samplers import samplers , samplers_for_img2img
2022-09-27 19:56:18 +00:00
from modules . sd_hijack import model_hijack
2022-09-21 13:06:37 +00:00
import modules . ldsr_model
2022-09-03 14:21:15 +00:00
import modules . scripts
2022-09-07 10:35:02 +00:00
import modules . gfpgan_model
import modules . codeformer_model
2022-09-09 20:16:02 +00:00
import modules . styles
2022-09-23 19:49:21 +00:00
import modules . generation_parameters_copypaste
2022-10-05 20:16:27 +00:00
from modules import prompt_parser
2022-10-04 16:19:50 +00:00
from modules . images import save_image
2022-10-02 12:03:39 +00:00
import modules . textual_inversion . ui
2022-10-11 12:51:22 +00:00
import modules . hypernetworks . ui
2022-10-10 07:39:39 +00:00
import modules . images_history as img_his
2022-09-03 09:08:45 +00:00
2022-10-08 19:12:24 +00:00
# this is a fix for Windows users. Without it, javascript files will be served with text/html content-type and the browser will not show any UI
2022-09-03 09:08:45 +00:00
mimetypes . init ( )
mimetypes . add_type ( ' application/javascript ' , ' .js ' )
2022-09-05 16:37:11 +00:00
if not cmd_opts . share and not cmd_opts . listen :
2022-09-03 09:08:45 +00:00
# fix gradio phoning home
gradio . utils . version_check = lambda : None
gradio . utils . get_local_ip_address = lambda : ' 127.0.0.1 '
2022-10-11 09:40:27 +00:00
if cmd_opts . ngrok != None :
import modules . ngrok as ngrok
print ( ' ngrok authtoken detected, trying to connect... ' )
2022-10-16 00:24:01 +00:00
ngrok . connect ( cmd_opts . ngrok , cmd_opts . port if cmd_opts . port != None else 7860 , cmd_opts . ngrok_region )
2022-10-11 09:40:27 +00:00
2022-09-03 09:08:45 +00:00
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 ; }
2022-09-27 07:44:00 +00:00
. wrap . m - 12 : : before { content : " Loading... " }
2022-09-03 09:08:45 +00:00
. progress - bar { display : none ! important ; }
. meta - text { display : none ! important ; }
"""
2022-09-16 19:20:56 +00:00
# Using constants for these since the variation selector isn't visible.
# Important that they exactly match script.js for tooltip to work.
random_symbol = ' \U0001f3b2 \ufe0f ' # 🎲️
reuse_symbol = ' \u267b \ufe0f ' # ♻️
2022-09-23 19:49:21 +00:00
art_symbol = ' \U0001f3a8 ' # 🎨
paste_symbol = ' \u2199 \ufe0f ' # ↙
2022-10-02 19:08:23 +00:00
folder_symbol = ' \U0001f4c2 ' # 📂
2022-10-13 16:22:41 +00:00
refresh_symbol = ' \U0001f504 ' # 🔄
2022-10-15 11:22:30 +00:00
save_style_symbol = ' \U0001f4be ' # 💾
apply_style_symbol = ' \U0001f4cb ' # 📋
2022-10-13 16:22:41 +00:00
2022-09-16 19:20:56 +00:00
2022-09-03 09:08:45 +00:00
def plaintext_to_html ( text ) :
2022-09-10 11:53:38 +00:00
text = " <p> " + " <br> \n " . join ( [ f " { html . escape ( x ) } " for x in text . split ( ' \n ' ) ] ) + " </p> "
2022-09-03 09:08:45 +00:00
return text
def image_from_url_text ( filedata ) :
2022-10-15 12:44:46 +00:00
if type ( filedata ) == dict and filedata [ " is_file " ] :
filename = filedata [ " name " ]
tempdir = os . path . normpath ( tempfile . gettempdir ( ) )
normfn = os . path . normpath ( filename )
assert normfn . startswith ( tempdir ) , ' trying to open image file not in temporary directory '
return Image . open ( filename )
2022-09-03 09:08:45 +00:00
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 02:15:37 +00:00
2022-10-08 05:09:29 +00:00
def save_files ( js_data , images , do_make_zip , index ) :
2022-10-10 01:26:52 +00:00
import csv
2022-09-03 09:08:45 +00:00
filenames = [ ]
2022-10-08 05:09:29 +00:00
fullfns = [ ]
2022-09-03 09:08:45 +00:00
2022-10-08 19:12:24 +00:00
#quick dictionary to class object conversion. Its necessary due apply_filename_pattern requiring it
2022-09-28 08:53:40 +00:00
class MyObject :
def __init__ ( self , d = None ) :
if d is not None :
for key , value in d . items ( ) :
setattr ( self , key , value )
2022-09-03 09:08:45 +00:00
data = json . loads ( js_data )
2022-09-29 10:19:13 +00:00
2022-09-28 08:53:40 +00:00
p = MyObject ( data )
path = opts . outdir_save
2022-10-02 16:15:31 +00:00
save_to_dirs = opts . use_save_to_dirs_for_ui
2022-10-04 16:19:50 +00:00
extension : str = opts . samples_format
start_index = 0
2022-09-29 10:19:13 +00:00
2022-09-28 14:05:23 +00:00
if index > - 1 and opts . save_selected_only and ( index > = data [ " index_of_first_image " ] ) : # ensures we are looking at a specific non-grid picture, and we have save_selected_only
2022-09-29 10:19:13 +00:00
2022-09-14 02:11:46 +00:00
images = [ images [ index ] ]
2022-10-04 16:19:50 +00:00
start_index = index
2022-09-03 09:08:45 +00:00
2022-10-12 04:54:24 +00:00
os . makedirs ( opts . outdir_save , exist_ok = True )
2022-09-03 18:33:47 +00:00
with open ( os . path . join ( opts . outdir_save , " log.csv " ) , " a " , encoding = " utf8 " , newline = ' ' ) as file :
2022-09-03 09:08:45 +00:00
at_start = file . tell ( ) == 0
writer = csv . writer ( file )
if at_start :
2022-09-12 16:57:31 +00:00
writer . writerow ( [ " prompt " , " seed " , " width " , " height " , " sampler " , " cfgs " , " steps " , " filename " , " negative_prompt " ] )
2022-09-03 09:08:45 +00:00
2022-10-04 16:19:50 +00:00
for image_index , filedata in enumerate ( images , start_index ) :
2022-10-15 14:25:35 +00:00
image = image_from_url_text ( filedata )
2022-09-03 09:08:45 +00:00
2022-10-04 16:19:50 +00:00
is_grid = image_index < p . index_of_first_image
i = 0 if is_grid else ( image_index - p . index_of_first_image )
2022-10-13 06:09:30 +00:00
fullfn , txt_fullfn = save_image ( image , path , " " , seed = p . all_seeds [ i ] , prompt = p . all_prompts [ i ] , extension = extension , info = p . infotexts [ image_index ] , grid = is_grid , p = p , save_to_dirs = save_to_dirs )
2022-10-04 16:19:50 +00:00
filename = os . path . relpath ( fullfn , path )
2022-09-03 09:08:45 +00:00
filenames . append ( filename )
2022-10-08 05:09:29 +00:00
fullfns . append ( fullfn )
2022-10-09 05:01:10 +00:00
if txt_fullfn :
filenames . append ( os . path . basename ( txt_fullfn ) )
fullfns . append ( txt_fullfn )
2022-09-03 09:08:45 +00:00
2022-10-13 06:09:30 +00: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 09:08:45 +00:00
2022-10-08 05:09:29 +00:00
# Make Zip
if do_make_zip :
zip_filepath = os . path . join ( path , " images.zip " )
from zipfile import ZipFile
with ZipFile ( zip_filepath , " w " ) as zip_file :
for i in range ( len ( fullfns ) ) :
with open ( fullfns [ i ] , mode = " rb " ) as f :
zip_file . writestr ( filenames [ i ] , f . read ( ) )
fullfns . insert ( 0 , zip_filepath )
2022-10-09 08:59:41 +00:00
return gr . File . update ( value = fullfns , visible = True ) , ' ' , ' ' , plaintext_to_html ( f " Saved: { filenames [ 0 ] } " )
2022-09-03 09:08:45 +00:00
2022-10-15 10:11:28 +00:00
def save_pil_to_file ( pil_image , dir = None ) :
use_metadata = False
metadata = PngImagePlugin . PngInfo ( )
for key , value in pil_image . info . items ( ) :
if isinstance ( key , str ) and isinstance ( value , str ) :
metadata . add_text ( key , value )
use_metadata = True
file_obj = tempfile . NamedTemporaryFile ( delete = False , suffix = " .png " , dir = dir )
pil_image . save ( file_obj , pnginfo = ( metadata if use_metadata else None ) )
return file_obj
# override save to file function so that it also writes PNG info
gr . processing_utils . save_pil_to_file = save_pil_to_file
2022-10-02 12:03:39 +00:00
def wrap_gradio_call ( func , extra_outputs = None ) :
def f ( * args , extra_outputs_array = extra_outputs , * * kwargs ) :
2022-09-18 11:03:17 +00:00
run_memmon = opts . memmon_poll_rate > 0 and not shared . mem_mon . disabled
if run_memmon :
2022-09-18 09:20:33 +00:00
shared . mem_mon . monitor ( )
2022-09-03 09:08:45 +00:00
t = time . perf_counter ( )
try :
res = list ( func ( * args , * * kwargs ) )
except Exception as e :
2022-10-12 02:29:38 +00:00
# When printing out our debug argument list, do not print out more than a MB of text
max_debug_str_len = 131072 # (1024*1024)/8
2022-09-03 09:08:45 +00:00
print ( " Error completing request " , file = sys . stderr )
2022-10-12 02:29:38 +00:00
argStr = f " Arguments: { str ( args ) } { str ( kwargs ) } "
print ( argStr [ : max_debug_str_len ] , file = sys . stderr )
if len ( argStr ) > max_debug_str_len :
print ( f " (Argument list truncated at { max_debug_str_len } / { len ( argStr ) } characters) " , file = sys . stderr )
2022-09-03 09:08:45 +00:00
print ( traceback . format_exc ( ) , file = sys . stderr )
2022-09-06 16:33:51 +00:00
shared . state . job = " "
shared . state . job_count = 0
2022-10-02 12:03:39 +00:00
if extra_outputs_array is None :
extra_outputs_array = [ None , ' ' ]
res = extra_outputs_array + [ f " <div class= ' error ' > { plaintext_to_html ( type ( e ) . __name__ + ' : ' + str ( e ) ) } </div> " ]
2022-09-03 09:08:45 +00:00
elapsed = time . perf_counter ( ) - t
2022-10-04 19:12:38 +00:00
elapsed_m = int ( elapsed / / 60 )
elapsed_s = elapsed % 60
elapsed_text = f " { elapsed_s : .2f } s "
if ( elapsed_m > 0 ) :
elapsed_text = f " { elapsed_m } m " + elapsed_text
2022-09-03 09:08:45 +00:00
2022-09-18 11:03:17 +00:00
if run_memmon :
2022-09-18 09:20:33 +00:00
mem_stats = { k : - ( v / / - ( 1024 * 1024 ) ) for k , v in shared . mem_mon . stop ( ) . items ( ) }
active_peak = mem_stats [ ' active_peak ' ]
reserved_peak = mem_stats [ ' reserved_peak ' ]
sys_peak = mem_stats [ ' system_peak ' ]
sys_total = mem_stats [ ' total ' ]
sys_pct = round ( sys_peak / max ( sys_total , 1 ) * 100 , 2 )
2022-09-18 21:10:32 +00:00
vram_html = f " <p class= ' vram ' >Torch active/reserved: { active_peak } / { reserved_peak } MiB, <wbr>Sys VRAM: { sys_peak } / { sys_total } MiB ( { sys_pct } %)</p> "
2022-09-18 09:20:33 +00:00
else :
vram_html = ' '
2022-09-17 06:23:31 +00:00
2022-09-03 09:08:45 +00:00
# last item is always HTML
2022-10-04 19:12:38 +00:00
res [ - 1 ] + = f " <div class= ' performance ' ><p class= ' time ' >Time taken: <wbr> { elapsed_text } </p> { vram_html } </div> "
2022-09-03 09:08:45 +00:00
2022-10-05 03:56:30 +00:00
shared . state . skipped = False
2022-09-03 09:08:45 +00:00
shared . state . interrupted = False
2022-10-02 12:03:39 +00:00
shared . state . job_count = 0
2022-09-03 09:08:45 +00:00
return tuple ( res )
return f
2022-10-19 17:53:52 +00:00
def calc_time_left ( progress , threshold , label , force_display , showTime ) :
2022-10-17 20:35:20 +00:00
if progress == 0 :
2022-10-18 17:38:07 +00:00
return " "
2022-10-17 20:35:20 +00:00
else :
time_since_start = time . time ( ) - shared . state . time_start
eta = ( time_since_start / progress )
2022-10-18 17:38:07 +00:00
eta_relative = eta - time_since_start
2022-10-19 17:53:52 +00:00
if ( eta_relative > threshold and showTime ) or force_display :
2022-10-19 16:28:27 +00:00
if eta_relative > 3600 :
return label + time . strftime ( ' % H: % M: % S ' , time . gmtime ( eta_relative ) )
elif eta_relative > 60 :
return label + time . strftime ( ' % M: % S ' , time . gmtime ( eta_relative ) )
else :
return label + time . strftime ( ' % Ss ' , time . gmtime ( eta_relative ) )
2022-10-18 17:38:07 +00:00
else :
return " "
2022-10-17 20:35:20 +00:00
2022-09-23 17:46:02 +00:00
def check_progress_call ( id_part ) :
2022-09-05 23:09:01 +00:00
if shared . state . job_count == 0 :
2022-10-02 12:03:39 +00:00
return " " , gr_show ( False ) , gr_show ( False ) , gr_show ( False )
2022-09-05 23:09:01 +00:00
2022-09-06 07:11:25 +00:00
progress = 0
if shared . state . job_count > 0 :
progress + = shared . state . job_no / shared . state . job_count
2022-09-05 23:09:01 +00:00
if shared . state . sampling_steps > 0 :
progress + = 1 / shared . state . job_count * shared . state . sampling_step / shared . state . sampling_steps
2022-10-19 17:53:52 +00:00
# Show progress percentage and time left at the same moment, and base it also on steps done
showPBText = progress > = 0.01 or shared . state . sampling_step > = 10
time_left = calc_time_left ( progress , 1 , " ETA: " , shared . state . time_left_force_display , showPBText )
2022-10-18 17:38:07 +00:00
if time_left != " " :
shared . state . time_left_force_display = True
2022-10-17 20:35:20 +00:00
2022-09-05 23:09:01 +00:00
progress = min ( progress , 1 )
2022-09-06 16:33:51 +00:00
progressbar = " "
if opts . show_progressbar :
2022-10-19 17:53:52 +00:00
progressbar = f """ <div class= ' progressDiv ' ><div class= ' progress ' style= " overflow:visible;width: { progress * 100 } %;white-space:nowrap; " > { " " * 2 + str ( int ( progress * 100 ) ) + " % " + time_left if showPBText else " " } </div></div> """
2022-09-06 16:33:51 +00:00
image = gr_show ( False )
preview_visibility = gr_show ( False )
if opts . show_progress_every_n_steps > 0 :
2022-09-06 20:10:12 +00:00
if shared . parallel_processing_allowed :
2022-09-06 16:33:51 +00:00
2022-09-06 20:10:12 +00: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 17:26:09 +00:00
2022-09-06 16:33:51 +00:00
image = shared . state . current_image
2022-09-24 06:16:54 +00:00
if image is None :
2022-09-06 16:33:51 +00:00
image = gr . update ( value = None )
else :
preview_visibility = gr_show ( True )
2022-09-05 23:09:01 +00:00
2022-10-02 12:03:39 +00:00
if shared . state . textinfo is not None :
textinfo_result = gr . HTML . update ( value = shared . state . textinfo , visible = True )
else :
textinfo_result = gr_show ( False )
return f " <span id= ' { id_part } _progress_span ' style= ' display: none ' > { time . time ( ) } </span><p> { progressbar } </p> " , preview_visibility , image , textinfo_result
2022-09-05 23:09:01 +00:00
2022-09-23 17:46:02 +00:00
def check_progress_call_initial ( id_part ) :
2022-09-18 08:14:42 +00:00
shared . state . job_count = - 1
2022-09-18 13:36:34 +00:00
shared . state . current_latent = None
shared . state . current_image = None
2022-10-02 12:03:39 +00:00
shared . state . textinfo = None
2022-10-17 20:35:20 +00:00
shared . state . time_start = time . time ( )
2022-10-18 17:38:07 +00:00
shared . state . time_left_force_display = False
2022-09-18 08:14:42 +00:00
2022-09-23 17:46:02 +00:00
return check_progress_call ( id_part )
2022-09-18 08:14:42 +00:00
2022-09-05 20:08:06 +00: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 10:52:01 +00: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 09:08:45 +00:00
2022-09-11 14:35:12 +00:00
def add_style ( name : str , prompt : str , negative_prompt : str ) :
if name is None :
2022-10-15 11:22:30 +00:00
return [ gr_show ( ) for x in range ( 4 ) ]
2022-09-09 20:16:02 +00:00
2022-09-11 14:35:12 +00:00
style = modules . styles . PromptStyle ( name , prompt , negative_prompt )
2022-09-14 14:56:21 +00:00
shared . prompt_styles . styles [ style . name ] = style
2022-09-11 14:35:12 +00: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 14:56:21 +00:00
shared . prompt_styles . save_styles ( shared . styles_filename )
2022-09-09 20:16:02 +00:00
2022-09-23 17:46:02 +00:00
return [ gr . Dropdown . update ( visible = True , choices = list ( shared . prompt_styles . styles ) ) for _ in range ( 4 ) ]
2022-09-14 14:56:21 +00:00
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 20:16:02 +00:00
2022-09-11 15:48:36 +00:00
def interrogate ( image ) :
prompt = shared . interrogator . interrogate ( image )
return gr_show ( True ) if prompt is None else prompt
2022-09-14 14:56:21 +00:00
2022-10-05 18:50:10 +00:00
def interrogate_deepbooru ( image ) :
prompt = get_deepbooru_tags ( image )
return gr_show ( True ) if prompt is None else prompt
2022-09-16 19:20:56 +00:00
def create_seed_inputs ( ) :
with gr . Row ( ) :
with gr . Box ( ) :
with gr . Row ( elem_id = ' seed_row ' ) :
2022-09-20 17:10:01 +00:00
seed = ( gr . Textbox if cmd_opts . use_textbox_seed else gr . Number ) ( label = ' Seed ' , value = - 1 )
2022-09-16 19:20:56 +00:00
seed . style ( container = False )
2022-09-18 15:10:22 +00:00
random_seed = gr . Button ( random_symbol , elem_id = ' random_seed ' )
reuse_seed = gr . Button ( reuse_symbol , elem_id = ' reuse_seed ' )
2022-09-16 19:20:56 +00:00
with gr . Box ( elem_id = ' subseed_show_box ' ) :
seed_checkbox = gr . Checkbox ( label = ' Extra ' , elem_id = ' subseed_show ' , value = False )
# Components to show/hide based on the 'Extra' checkbox
seed_extras = [ ]
with gr . Row ( visible = False ) as seed_extra_row_1 :
seed_extras . append ( seed_extra_row_1 )
with gr . Box ( ) :
with gr . Row ( elem_id = ' subseed_row ' ) :
subseed = gr . Number ( label = ' Variation seed ' , value = - 1 )
subseed . style ( container = False )
random_subseed = gr . Button ( random_symbol , elem_id = ' random_subseed ' )
reuse_subseed = gr . Button ( reuse_symbol , elem_id = ' reuse_subseed ' )
subseed_strength = gr . Slider ( label = ' Variation strength ' , value = 0.0 , minimum = 0 , maximum = 1 , step = 0.01 )
with gr . Row ( visible = False ) as seed_extra_row_2 :
seed_extras . append ( seed_extra_row_2 )
seed_resize_from_w = gr . Slider ( minimum = 0 , maximum = 2048 , step = 64 , label = " Resize seed from width " , value = 0 )
seed_resize_from_h = gr . Slider ( minimum = 0 , maximum = 2048 , step = 64 , label = " Resize seed from height " , value = 0 )
random_seed . click ( fn = lambda : - 1 , show_progress = False , inputs = [ ] , outputs = [ seed ] )
random_subseed . click ( fn = lambda : - 1 , show_progress = False , inputs = [ ] , outputs = [ subseed ] )
def change_visibility ( show ) :
return { comp : gr_show ( show ) for comp in seed_extras }
seed_checkbox . change ( change_visibility , show_progress = False , inputs = [ seed_checkbox ] , outputs = seed_extras )
2022-09-21 10:34:10 +00:00
return seed , reuse_seed , subseed , reuse_subseed , subseed_strength , seed_resize_from_h , seed_resize_from_w , seed_checkbox
2022-09-16 19:20:56 +00:00
2022-09-19 06:02:10 +00:00
def connect_reuse_seed ( seed : gr . Number , reuse_seed : gr . Button , generation_info : gr . Textbox , dummy_component , is_subseed ) :
""" Connects a ' reuse (sub)seed ' button ' s click event so that it copies last used
( sub ) seed value from generation info the to the seed field . If copying subseed and subseed strength
2022-09-16 19:20:56 +00:00
was 0 , i . e . no variation seed was used , it copies the normal seed value instead . """
2022-09-19 06:02:10 +00:00
def copy_seed ( gen_info_string : str , index ) :
res = - 1
2022-09-16 19:20:56 +00:00
try :
gen_info = json . loads ( gen_info_string )
2022-09-19 06:02:10 +00:00
index - = gen_info . get ( ' index_of_first_image ' , 0 )
if is_subseed and gen_info . get ( ' subseed_strength ' , 0 ) > 0 :
all_subseeds = gen_info . get ( ' all_subseeds ' , [ - 1 ] )
res = all_subseeds [ index if 0 < = index < len ( all_subseeds ) else 0 ]
2022-09-16 19:20:56 +00:00
else :
2022-09-19 06:02:10 +00:00
all_seeds = gen_info . get ( ' all_seeds ' , [ - 1 ] )
res = all_seeds [ index if 0 < = index < len ( all_seeds ) else 0 ]
2022-09-16 19:20:56 +00:00
except json . decoder . JSONDecodeError as e :
if gen_info_string != ' ' :
print ( " Error parsing JSON generation info: " , file = sys . stderr )
print ( gen_info_string , file = sys . stderr )
2022-09-19 06:02:10 +00:00
return [ res , gr_show ( False ) ]
2022-09-16 19:20:56 +00:00
reuse_seed . click (
fn = copy_seed ,
2022-09-19 06:02:10 +00:00
_js = " (x, y) => [x, selected_gallery_index()] " ,
2022-09-16 19:20:56 +00:00
show_progress = False ,
2022-09-19 06:02:10 +00:00
inputs = [ generation_info , dummy_component ] ,
outputs = [ seed , dummy_component ]
2022-09-16 19:20:56 +00:00
)
2022-10-04 11:35:12 +00:00
2022-09-29 19:47:06 +00:00
def update_token_counter ( text , steps ) :
2022-10-04 11:35:12 +00:00
try :
2022-10-05 20:16:27 +00:00
_ , prompt_flat_list , _ = prompt_parser . get_multicond_prompt_list ( [ text ] )
prompt_schedules = prompt_parser . get_learned_conditioning_prompt_schedules ( prompt_flat_list , steps )
2022-10-04 11:35:12 +00:00
except Exception :
# a parsing error can happen here during typing, and we don't want to bother the user with
# messages related to it in console
prompt_schedules = [ [ [ steps , text ] ] ]
2022-09-29 19:47:06 +00:00
flat_prompts = reduce ( lambda list1 , list2 : list1 + list2 , prompt_schedules )
2022-10-04 11:35:12 +00:00
prompts = [ prompt_text for step , prompt_text in flat_prompts ]
2022-09-29 19:47:06 +00:00
tokens , token_count , max_length = max ( [ model_hijack . tokenize ( prompt ) for prompt in prompts ] , key = lambda args : args [ 1 ] )
2022-09-27 23:29:53 +00:00
style_class = ' class= " red " ' if ( token_count > max_length ) else " "
return f " <span { style_class } > { token_count } / { max_length } </span> "
2022-09-19 13:42:56 +00:00
2022-10-04 11:35:12 +00:00
2022-09-14 14:56:21 +00:00
def create_toprow ( is_img2img ) :
2022-09-23 17:46:02 +00:00
id_part = " img2img " if is_img2img else " txt2img "
2022-09-14 14:56:21 +00:00
with gr . Row ( elem_id = " toprow " ) :
2022-10-15 11:22:30 +00:00
with gr . Column ( scale = 6 ) :
2022-09-14 14:56:21 +00:00
with gr . Row ( ) :
2022-09-23 17:54:17 +00:00
with gr . Column ( scale = 80 ) :
2022-09-14 14:56:21 +00:00
with gr . Row ( ) :
2022-10-19 14:30:33 +00:00
prompt = gr . Textbox ( label = " Prompt " , elem_id = f " { id_part } _prompt " , show_label = False , lines = 2 ,
2022-10-15 03:48:13 +00:00
placeholder = " Prompt (press Ctrl+Enter or Alt+Enter to generate) "
)
2022-09-14 14:56:21 +00:00
with gr . Row ( ) :
2022-10-15 11:22:30 +00:00
with gr . Column ( scale = 80 ) :
2022-10-11 07:08:45 +00:00
with gr . Row ( ) :
2022-10-19 14:30:33 +00:00
negative_prompt = gr . Textbox ( label = " Negative prompt " , elem_id = f " { id_part } _neg_prompt " , show_label = False , lines = 2 ,
2022-10-15 03:48:13 +00:00
placeholder = " Negative prompt (press Ctrl+Enter or Alt+Enter to generate) "
)
2022-10-15 11:22:30 +00:00
with gr . Column ( scale = 1 , elem_id = " roll_col " ) :
roll = gr . Button ( value = art_symbol , elem_id = " roll " , visible = len ( shared . artist_db . artists ) > 0 )
paste = gr . Button ( value = paste_symbol , elem_id = " paste " )
save_style = gr . Button ( value = save_style_symbol , elem_id = " style_create " )
prompt_style_apply = gr . Button ( value = apply_style_symbol , elem_id = " style_apply " )
2022-09-14 14:56:21 +00:00
2022-10-15 11:22:30 +00:00
token_counter = gr . HTML ( value = " <span></span> " , elem_id = f " { id_part } _token_counter " )
token_button = gr . Button ( visible = False , elem_id = f " { id_part } _token_button " )
button_interrogate = None
button_deepbooru = None
if is_img2img :
with gr . Column ( scale = 1 , elem_id = " interrogate_col " ) :
button_interrogate = gr . Button ( ' Interrogate \n CLIP ' , elem_id = " interrogate " )
if cmd_opts . deepdanbooru :
button_deepbooru = gr . Button ( ' Interrogate \n DeepBooru ' , elem_id = " deepbooru " )
2022-09-14 14:56:21 +00:00
with gr . Column ( scale = 1 ) :
with gr . Row ( ) :
2022-10-05 03:56:30 +00:00
skip = gr . Button ( ' Skip ' , elem_id = f " { id_part } _skip " )
2022-09-23 17:46:02 +00:00
interrupt = gr . Button ( ' Interrupt ' , elem_id = f " { id_part } _interrupt " )
2022-09-30 20:31:00 +00:00
submit = gr . Button ( ' Generate ' , elem_id = f " { id_part } _generate " , variant = ' primary ' )
2022-09-22 01:12:39 +00:00
2022-10-05 03:56:30 +00:00
skip . click (
fn = lambda : shared . state . skip ( ) ,
inputs = [ ] ,
outputs = [ ] ,
)
2022-09-22 01:12:39 +00:00
interrupt . click (
fn = lambda : shared . state . interrupt ( ) ,
inputs = [ ] ,
outputs = [ ] ,
)
2022-09-14 14:56:21 +00:00
2022-10-15 11:22:30 +00:00
with gr . Row ( ) :
with gr . Column ( scale = 1 , elem_id = " style_pos_col " ) :
prompt_style = gr . Dropdown ( label = " Style 1 " , elem_id = f " { id_part } _style_index " , choices = [ k for k , v in shared . prompt_styles . styles . items ( ) ] , value = next ( iter ( shared . prompt_styles . styles . keys ( ) ) ) )
2022-10-15 19:47:03 +00:00
prompt_style . save_to_config = True
2022-10-15 11:22:30 +00:00
with gr . Column ( scale = 1 , elem_id = " style_neg_col " ) :
prompt_style2 = gr . Dropdown ( label = " Style 2 " , elem_id = f " { id_part } _style2_index " , choices = [ k for k , v in shared . prompt_styles . styles . items ( ) ] , value = next ( iter ( shared . prompt_styles . styles . keys ( ) ) ) )
2022-10-15 19:47:03 +00:00
prompt_style2 . save_to_config = True
2022-10-15 11:22:30 +00:00
return prompt , roll , prompt_style , negative_prompt , prompt_style2 , submit , button_interrogate , button_deepbooru , prompt_style_apply , save_style , paste , token_counter , token_button
2022-09-14 14:56:21 +00:00
2022-10-02 12:03:39 +00:00
def setup_progressbar ( progressbar , preview , id_part , textinfo = None ) :
if textinfo is None :
textinfo = gr . HTML ( visible = False )
2022-09-18 08:14:42 +00:00
2022-09-23 17:46:02 +00:00
check_progress = gr . Button ( ' Check progress ' , elem_id = f " { id_part } _check_progress " , visible = False )
2022-09-18 08:14:42 +00:00
check_progress . click (
2022-09-23 17:46:02 +00:00
fn = lambda : check_progress_call ( id_part ) ,
2022-09-18 08:14:42 +00:00
show_progress = False ,
inputs = [ ] ,
2022-10-02 12:03:39 +00:00
outputs = [ progressbar , preview , preview , textinfo ] ,
2022-09-18 08:14:42 +00:00
)
2022-09-23 17:46:02 +00:00
check_progress_initial = gr . Button ( ' Check progress (first) ' , elem_id = f " { id_part } _check_progress_initial " , visible = False )
2022-09-18 08:14:42 +00:00
check_progress_initial . click (
2022-09-23 17:46:02 +00:00
fn = lambda : check_progress_call_initial ( id_part ) ,
2022-09-18 08:14:42 +00:00
show_progress = False ,
inputs = [ ] ,
2022-10-02 12:03:39 +00:00
outputs = [ progressbar , preview , preview , textinfo ] ,
2022-09-18 08:14:42 +00:00
)
2022-09-14 14:56:21 +00:00
2022-10-14 16:30:28 +00:00
def apply_setting ( key , value ) :
if value is None :
return gr . update ( )
2022-10-17 14:58:21 +00:00
# dont allow model to be swapped when model hash exists in prompt
if key == " sd_model_checkpoint " and opts . disable_weights_auto_swap :
return gr . update ( )
2022-10-14 16:30:28 +00:00
if key == " sd_model_checkpoint " :
ckpt_info = sd_models . get_closet_checkpoint_match ( value )
if ckpt_info is not None :
value = ckpt_info . title
else :
return gr . update ( )
comp_args = opts . data_labels [ key ] . component_args
if comp_args and isinstance ( comp_args , dict ) and comp_args . get ( ' visible ' ) is False :
return
valtype = type ( opts . data_labels [ key ] . default )
oldval = opts . data [ key ]
opts . data [ key ] = valtype ( value ) if valtype != type ( None ) else value
if oldval != value and opts . data_labels [ key ] . onchange is not None :
opts . data_labels [ key ] . onchange ( )
opts . save ( shared . config_filename )
return value
2022-10-02 12:03:39 +00:00
def create_ui ( wrap_gradio_gpu_call ) :
import modules . img2img
import modules . txt2img
2022-10-16 04:42:52 +00:00
def create_refresh_button ( refresh_component , refresh_method , refreshed_args , elem_id ) :
def refresh ( ) :
refresh_method ( )
args = refreshed_args ( ) if callable ( refreshed_args ) else refreshed_args
for k , v in args . items ( ) :
setattr ( refresh_component , k , v )
return gr . update ( * * ( args or { } ) )
refresh_button = gr . Button ( value = refresh_symbol , elem_id = elem_id )
refresh_button . click (
fn = refresh ,
inputs = [ ] ,
outputs = [ refresh_component ]
)
return refresh_button
2022-09-03 09:08:45 +00:00
with gr . Blocks ( analytics_enabled = False ) as txt2img_interface :
2022-10-14 16:30:28 +00:00
txt2img_prompt , roll , txt2img_prompt_style , txt2img_negative_prompt , txt2img_prompt_style2 , submit , _ , _ , txt2img_prompt_style_apply , txt2img_save_style , txt2img_paste , token_counter , token_button = create_toprow ( is_img2img = False )
2022-09-19 06:02:10 +00:00
dummy_component = gr . Label ( visible = False )
2022-10-14 15:15:03 +00:00
txt_prompt_img = gr . File ( label = " " , elem_id = " txt2img_prompt_image " , file_count = " single " , type = " bytes " , visible = False )
2022-09-03 09:08:45 +00:00
2022-09-23 17:46:02 +00:00
with gr . Row ( elem_id = ' txt2img_progress_row ' ) :
with gr . Column ( scale = 1 ) :
pass
2022-09-22 01:12:39 +00:00
2022-09-23 17:46:02 +00:00
with gr . Column ( scale = 1 ) :
progressbar = gr . HTML ( elem_id = " txt2img_progressbar " )
2022-09-22 01:12:39 +00:00
txt2img_preview = gr . Image ( elem_id = ' txt2img_preview ' , visible = False )
2022-09-23 17:46:02 +00:00
setup_progressbar ( progressbar , txt2img_preview , ' txt2img ' )
2022-09-22 01:12:39 +00:00
2022-09-03 09:08:45 +00: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 " )
2022-09-25 05:40:29 +00:00
with gr . Group ( ) :
width = gr . Slider ( minimum = 64 , maximum = 2048 , step = 64 , label = " Width " , value = 512 )
height = gr . Slider ( minimum = 64 , maximum = 2048 , step = 64 , label = " Height " , value = 512 )
2022-09-03 09:08:45 +00:00
with gr . Row ( ) :
2022-09-07 09:32:28 +00:00
restore_faces = gr . Checkbox ( label = ' Restore faces ' , value = False , visible = len ( shared . face_restorers ) > 1 )
2022-09-05 00:25:37 +00:00
tiling = gr . Checkbox ( label = ' Tiling ' , value = False )
2022-09-19 13:42:56 +00:00
enable_hr = gr . Checkbox ( label = ' Highres. fix ' , value = False )
with gr . Row ( visible = False ) as hr_options :
2022-10-14 21:21:48 +00:00
firstphase_width = gr . Slider ( minimum = 0 , maximum = 1024 , step = 64 , label = " Firstpass width " , value = 0 )
firstphase_height = gr . Slider ( minimum = 0 , maximum = 1024 , step = 64 , label = " Firstpass height " , value = 0 )
2022-10-14 14:03:03 +00:00
denoising_strength = gr . Slider ( minimum = 0.0 , maximum = 1.0 , step = 0.01 , label = ' Denoising strength ' , value = 0.7 )
2022-10-13 19:04:22 +00:00
with gr . Row ( equal_height = True ) :
2022-10-10 01:44:11 +00:00
batch_count = gr . Slider ( minimum = 1 , step = 1 , label = ' Batch count ' , value = 1 )
2022-09-03 09:08:45 +00:00
batch_size = gr . Slider ( minimum = 1 , maximum = 8 , step = 1 , label = ' Batch size ' , value = 1 )
2022-09-12 08:55:27 +00:00
cfg_scale = gr . Slider ( minimum = 1.0 , maximum = 30.0 , step = 0.5 , label = ' CFG Scale ' , value = 7.0 )
2022-09-03 09:08:45 +00:00
2022-09-21 10:34:10 +00:00
seed , reuse_seed , subseed , reuse_subseed , subseed_strength , seed_resize_from_h , seed_resize_from_w , seed_checkbox = create_seed_inputs ( )
2022-09-03 09:08:45 +00:00
2022-09-03 14:21:15 +00:00
with gr . Group ( ) :
2022-09-03 22:29:43 +00:00
custom_inputs = modules . scripts . scripts_txt2img . setup_ui ( is_img2img = False )
2022-09-03 09:08:45 +00:00
with gr . Column ( variant = ' panel ' ) :
2022-09-17 09:38:15 +00:00
2022-09-03 09:08:45 +00:00
with gr . Group ( ) :
2022-09-06 16:33:51 +00:00
txt2img_preview = gr . Image ( elem_id = ' txt2img_preview ' , visible = False )
2022-09-22 09:30:11 +00:00
txt2img_gallery = gr . Gallery ( label = ' Output ' , show_label = False , elem_id = ' txt2img_gallery ' ) . style ( grid = 4 )
2022-09-03 09:08:45 +00:00
2022-10-15 09:00:46 +00:00
with gr . Column ( ) :
2022-09-03 09:08:45 +00:00
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 ' )
2022-09-28 08:40:05 +00:00
button_id = " hidden_element " if shared . cmd_opts . hide_ui_dir_config else ' open_folder '
2022-09-28 08:31:53 +00:00
open_txt2img_folder = gr . Button ( folder_symbol , elem_id = button_id )
2022-09-03 09:08:45 +00:00
2022-10-08 05:09:29 +00:00
with gr . Row ( ) :
do_make_zip = gr . Checkbox ( label = " Make Zip when Save? " , value = False )
2022-10-10 01:26:52 +00:00
2022-10-08 05:09:29 +00:00
with gr . Row ( ) :
2022-10-09 08:59:41 +00:00
download_files = gr . File ( None , file_count = " multiple " , interactive = False , show_label = False , visible = False )
2022-10-08 05:09:29 +00:00
2022-10-10 18:37:16 +00:00
with gr . Group ( ) :
html_info = gr . HTML ( )
generation_info = gr . Textbox ( visible = False )
2022-09-03 09:08:45 +00:00
2022-09-19 06:02:10 +00:00
connect_reuse_seed ( seed , reuse_seed , generation_info , dummy_component , is_subseed = False )
connect_reuse_seed ( subseed , reuse_subseed , generation_info , dummy_component , is_subseed = True )
2022-09-16 19:20:56 +00:00
2022-09-03 09:08:45 +00:00
txt2img_args = dict (
2022-10-02 12:03:39 +00:00
fn = wrap_gradio_gpu_call ( modules . txt2img . txt2img ) ,
2022-09-05 23:09:01 +00:00
_js = " submit " ,
2022-09-03 09:08:45 +00:00
inputs = [
2022-09-09 20:16:02 +00:00
txt2img_prompt ,
2022-09-11 14:35:12 +00:00
txt2img_negative_prompt ,
2022-09-09 20:16:02 +00:00
txt2img_prompt_style ,
2022-09-14 14:56:21 +00:00
txt2img_prompt_style2 ,
2022-09-03 09:08:45 +00:00
steps ,
sampler_index ,
2022-09-07 09:32:28 +00:00
restore_faces ,
2022-09-05 00:25:37 +00:00
tiling ,
2022-09-03 09:08:45 +00:00
batch_count ,
batch_size ,
cfg_scale ,
seed ,
2022-09-21 10:34:10 +00:00
subseed , subseed_strength , seed_resize_from_h , seed_resize_from_w , seed_checkbox ,
2022-09-03 09:08:45 +00:00
height ,
width ,
2022-09-19 13:42:56 +00:00
enable_hr ,
denoising_strength ,
2022-10-13 19:04:22 +00:00
firstphase_width ,
firstphase_height ,
2022-09-03 14:21:15 +00:00
] + custom_inputs ,
2022-09-03 09:08:45 +00:00
outputs = [
txt2img_gallery ,
generation_info ,
html_info
2022-09-18 08:14:42 +00:00
] ,
show_progress = False ,
2022-09-03 09:08:45 +00:00
)
2022-09-09 20:16:02 +00:00
txt2img_prompt . submit ( * * txt2img_args )
2022-09-03 09:08:45 +00:00
submit . click ( * * txt2img_args )
2022-10-12 23:17:26 +00:00
txt_prompt_img . change (
fn = modules . images . image_data ,
inputs = [
txt_prompt_img
] ,
outputs = [
txt2img_prompt ,
txt_prompt_img
]
)
2022-09-19 13:42:56 +00:00
enable_hr . change (
fn = lambda x : gr_show ( x ) ,
inputs = [ enable_hr ] ,
outputs = [ hr_options ] ,
)
2022-09-03 09:08:45 +00:00
save . click (
fn = wrap_gradio_call ( save_files ) ,
2022-10-08 05:09:29 +00:00
_js = " (x, y, z, w) => [x, y, z, selected_gallery_index()] " ,
2022-09-03 09:08:45 +00:00
inputs = [
generation_info ,
txt2img_gallery ,
2022-10-08 05:09:29 +00:00
do_make_zip ,
2022-09-19 06:02:10 +00:00
html_info ,
2022-09-03 09:08:45 +00:00
] ,
outputs = [
2022-10-08 05:09:29 +00:00
download_files ,
2022-09-03 09:08:45 +00:00
html_info ,
html_info ,
html_info ,
]
)
2022-09-05 20:08:06 +00:00
roll . click (
fn = roll_artist ,
2022-09-30 16:12:44 +00:00
_js = " update_txt2img_tokens " ,
2022-09-05 20:08:06 +00:00
inputs = [
2022-09-09 20:16:02 +00:00
txt2img_prompt ,
2022-09-05 20:08:06 +00:00
] ,
outputs = [
2022-09-09 20:16:02 +00:00
txt2img_prompt ,
2022-09-05 20:08:06 +00:00
]
)
2022-09-25 06:25:28 +00:00
txt2img_paste_fields = [
( txt2img_prompt , " Prompt " ) ,
( txt2img_negative_prompt , " Negative prompt " ) ,
( steps , " Steps " ) ,
( sampler_index , " Sampler " ) ,
( restore_faces , " Face restoration " ) ,
( cfg_scale , " CFG scale " ) ,
( seed , " Seed " ) ,
( width , " Size-1 " ) ,
( height , " Size-2 " ) ,
( batch_size , " Batch size " ) ,
( subseed , " Variation seed " ) ,
( subseed_strength , " Variation seed strength " ) ,
( seed_resize_from_w , " Seed resize from-1 " ) ,
( seed_resize_from_h , " Seed resize from-2 " ) ,
( denoising_strength , " Denoising strength " ) ,
( enable_hr , lambda d : " Denoising strength " in d ) ,
( hr_options , lambda d : gr . Row . update ( visible = " Denoising strength " in d ) ) ,
2022-10-14 14:03:03 +00:00
( firstphase_width , " First pass size-1 " ) ,
( firstphase_height , " First pass size-2 " ) ,
2022-09-25 06:25:28 +00:00
]
2022-10-14 17:31:49 +00:00
txt2img_preview_params = [
txt2img_prompt ,
txt2img_negative_prompt ,
steps ,
sampler_index ,
cfg_scale ,
seed ,
width ,
height ,
]
2022-09-29 19:47:06 +00:00
token_button . click ( fn = update_token_counter , inputs = [ txt2img_prompt , steps ] , outputs = [ token_counter ] )
2022-09-23 19:49:21 +00:00
2022-09-03 09:08:45 +00:00
with gr . Blocks ( analytics_enabled = False ) as img2img_interface :
2022-10-14 16:30:28 +00:00
img2img_prompt , roll , img2img_prompt_style , img2img_negative_prompt , img2img_prompt_style2 , submit , img2img_interrogate , img2img_deepbooru , img2img_prompt_style_apply , img2img_save_style , img2img_paste , token_counter , token_button = create_toprow ( is_img2img = True )
2022-09-03 09:08:45 +00:00
2022-09-23 17:46:02 +00:00
with gr . Row ( elem_id = ' img2img_progress_row ' ) :
2022-10-14 15:15:03 +00:00
img2img_prompt_img = gr . File ( label = " " , elem_id = " img2img_prompt_image " , file_count = " single " , type = " bytes " , visible = False )
2022-10-12 23:17:26 +00:00
2022-09-23 17:46:02 +00:00
with gr . Column ( scale = 1 ) :
pass
2022-09-22 01:12:39 +00:00
2022-09-23 17:46:02 +00:00
with gr . Column ( scale = 1 ) :
progressbar = gr . HTML ( elem_id = " img2img_progressbar " )
2022-09-22 01:12:39 +00:00
img2img_preview = gr . Image ( elem_id = ' img2img_preview ' , visible = False )
2022-09-23 17:46:02 +00:00
setup_progressbar ( progressbar , img2img_preview , ' img2img ' )
2022-09-22 09:11:48 +00:00
2022-09-03 09:08:45 +00:00
with gr . Row ( ) . style ( equal_height = False ) :
with gr . Column ( variant = ' panel ' ) :
2022-09-09 16:43:16 +00:00
2022-09-22 09:11:48 +00:00
with gr . Tabs ( elem_id = " mode_img2img " ) as tabs_img2img_mode :
2022-09-23 19:49:21 +00:00
with gr . TabItem ( ' img2img ' , id = ' img2img ' ) :
2022-10-15 09:54:23 +00:00
init_img = gr . Image ( label = " Image for img2img " , elem_id = " img2img_image " , show_label = False , source = " upload " , interactive = True , type = " pil " , tool = cmd_opts . gradio_img2img_tool ) . style ( height = 480 )
2022-09-03 09:08:45 +00:00
2022-09-23 19:49:21 +00:00
with gr . TabItem ( ' Inpaint ' , id = ' inpaint ' ) :
2022-10-15 09:54:23 +00:00
init_img_with_mask = gr . Image ( label = " Image for inpainting with mask " , show_label = False , elem_id = " img2maskimg " , source = " upload " , interactive = True , type = " pil " , tool = " sketch " , image_mode = " RGBA " ) . style ( height = 480 )
2022-09-22 09:11:48 +00:00
2022-09-26 20:57:31 +00:00
init_img_inpaint = gr . Image ( label = " Image for img2img " , show_label = False , source = " upload " , interactive = True , type = " pil " , visible = False , elem_id = " img_inpaint_base " )
init_mask_inpaint = gr . Image ( label = " Mask " , source = " upload " , interactive = True , type = " pil " , visible = False , elem_id = " img_inpaint_mask " )
2022-09-22 09:11:48 +00:00
mask_blur = gr . Slider ( label = ' Mask blur ' , minimum = 0 , maximum = 64 , step = 1 , value = 4 )
with gr . Row ( ) :
2022-09-26 20:57:31 +00:00
mask_mode = gr . Radio ( label = " Mask mode " , show_label = False , choices = [ " Draw mask " , " Upload mask " ] , type = " index " , value = " Draw mask " , elem_id = " mask_mode " )
2022-09-22 09:11:48 +00:00
inpainting_mask_invert = gr . Radio ( label = ' Masking mode ' , show_label = False , choices = [ ' Inpaint masked ' , ' Inpaint not masked ' ] , value = ' Inpaint masked ' , type = " index " )
2022-09-30 15:07:49 +00:00
inpainting_fill = gr . Radio ( label = ' Masked content ' , choices = [ ' fill ' , ' original ' , ' latent noise ' , ' latent nothing ' ] , value = ' original ' , type = " index " )
2022-09-22 09:11:48 +00:00
with gr . Row ( ) :
inpaint_full_res = gr . Checkbox ( label = ' Inpaint at full resolution ' , value = False )
inpaint_full_res_padding = gr . Slider ( label = ' Inpaint at full resolution padding, pixels ' , minimum = 0 , maximum = 256 , step = 4 , value = 32 )
2022-09-23 19:49:21 +00:00
with gr . TabItem ( ' Batch img2img ' , id = ' batch ' ) :
2022-09-24 13:29:20 +00:00
hidden = ' <br>Disabled when launched with --hide-ui-dir-config. ' if shared . cmd_opts . hide_ui_dir_config else ' '
2022-10-03 08:48:19 +00:00
gr . HTML ( f " <p class= \" text-gray-500 \" >Process images in a directory on the same machine where the server is running.<br>Use an empty output directory to save pictures normally instead of writing to the output directory. { hidden } </p> " )
2022-09-24 13:29:20 +00:00
img2img_batch_input_dir = gr . Textbox ( label = " Input directory " , * * shared . hide_dirs )
img2img_batch_output_dir = gr . Textbox ( label = " Output directory " , * * shared . hide_dirs )
2022-09-03 09:08:45 +00:00
with gr . Row ( ) :
2022-09-22 09:11:48 +00:00
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 " )
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 " )
2022-09-03 18:02:38 +00:00
2022-09-25 05:40:29 +00:00
with gr . Group ( ) :
width = gr . Slider ( minimum = 64 , maximum = 2048 , step = 64 , label = " Width " , value = 512 )
height = gr . Slider ( minimum = 64 , maximum = 2048 , step = 64 , label = " Height " , value = 512 )
2022-09-03 18:02:38 +00:00
with gr . Row ( ) :
2022-09-07 09:32:28 +00:00
restore_faces = gr . Checkbox ( label = ' Restore faces ' , value = False , visible = len ( shared . face_restorers ) > 1 )
2022-09-05 00:25:37 +00:00
tiling = gr . Checkbox ( label = ' Tiling ' , value = False )
2022-09-03 09:08:45 +00:00
with gr . Row ( ) :
2022-10-10 01:44:11 +00:00
batch_count = gr . Slider ( minimum = 1 , step = 1 , label = ' Batch count ' , value = 1 )
2022-09-03 09:08:45 +00:00
batch_size = gr . Slider ( minimum = 1 , maximum = 8 , step = 1 , label = ' Batch size ' , value = 1 )
with gr . Group ( ) :
2022-09-12 08:55:27 +00:00
cfg_scale = gr . Slider ( minimum = 1.0 , maximum = 30.0 , step = 0.5 , label = ' CFG Scale ' , value = 7.0 )
2022-09-08 12:02:06 +00:00
denoising_strength = gr . Slider ( minimum = 0.0 , maximum = 1.0 , step = 0.01 , label = ' Denoising strength ' , value = 0.75 )
2022-09-03 09:08:45 +00:00
2022-09-21 10:34:10 +00:00
seed , reuse_seed , subseed , reuse_subseed , subseed_strength , seed_resize_from_h , seed_resize_from_w , seed_checkbox = create_seed_inputs ( )
2022-09-03 09:08:45 +00:00
2022-09-03 14:21:15 +00:00
with gr . Group ( ) :
2022-09-03 22:29:43 +00:00
custom_inputs = modules . scripts . scripts_img2img . setup_ui ( is_img2img = True )
2022-09-03 14:21:15 +00:00
2022-09-03 09:08:45 +00:00
with gr . Column ( variant = ' panel ' ) :
2022-09-17 09:38:15 +00:00
2022-09-03 09:08:45 +00:00
with gr . Group ( ) :
2022-09-06 16:33:51 +00:00
img2img_preview = gr . Image ( elem_id = ' img2img_preview ' , visible = False )
2022-09-22 09:30:11 +00:00
img2img_gallery = gr . Gallery ( label = ' Output ' , show_label = False , elem_id = ' img2img_gallery ' ) . style ( grid = 4 )
2022-09-03 09:08:45 +00:00
2022-10-15 09:00:46 +00:00
with gr . Column ( ) :
2022-09-03 09:08:45 +00:00
with gr . Row ( ) :
save = gr . Button ( ' Save ' )
2022-09-06 16:33:51 +00:00
img2img_send_to_img2img = gr . Button ( ' Send to img2img ' )
img2img_send_to_inpaint = gr . Button ( ' Send to inpaint ' )
2022-09-03 09:08:45 +00:00
img2img_send_to_extras = gr . Button ( ' Send to extras ' )
2022-09-28 08:40:05 +00:00
button_id = " hidden_element " if shared . cmd_opts . hide_ui_dir_config else ' open_folder '
2022-09-28 08:31:53 +00:00
open_img2img_folder = gr . Button ( folder_symbol , elem_id = button_id )
2022-09-03 09:08:45 +00:00
2022-10-08 05:09:29 +00:00
with gr . Row ( ) :
do_make_zip = gr . Checkbox ( label = " Make Zip when Save? " , value = False )
2022-10-10 01:26:52 +00:00
2022-10-08 05:09:29 +00:00
with gr . Row ( ) :
2022-10-09 08:59:41 +00:00
download_files = gr . File ( None , file_count = " multiple " , interactive = False , show_label = False , visible = False )
2022-10-08 05:09:29 +00:00
2022-10-10 18:37:16 +00:00
with gr . Group ( ) :
html_info = gr . HTML ( )
generation_info = gr . Textbox ( visible = False )
2022-09-03 09:08:45 +00:00
2022-09-19 06:02:10 +00:00
connect_reuse_seed ( seed , reuse_seed , generation_info , dummy_component , is_subseed = False )
connect_reuse_seed ( subseed , reuse_subseed , generation_info , dummy_component , is_subseed = True )
2022-09-16 19:20:56 +00:00
2022-10-12 23:17:26 +00:00
img2img_prompt_img . change (
fn = modules . images . image_data ,
inputs = [
2022-10-14 15:15:03 +00:00
img2img_prompt_img
2022-10-12 23:17:26 +00:00
] ,
outputs = [
img2img_prompt ,
img2img_prompt_img
]
)
2022-09-09 16:43:16 +00:00
mask_mode . change (
2022-09-22 09:11:48 +00:00
lambda mode , img : {
2022-09-09 16:43:16 +00:00
init_img_with_mask : gr_show ( mode == 0 ) ,
2022-09-22 09:11:48 +00:00
init_img_inpaint : gr_show ( mode == 1 ) ,
init_mask_inpaint : gr_show ( mode == 1 ) ,
2022-09-09 16:43:16 +00:00
} ,
2022-09-22 09:11:48 +00:00
inputs = [ mask_mode , init_img_with_mask ] ,
2022-09-09 16:43:16 +00:00
outputs = [
init_img_with_mask ,
2022-09-22 09:11:48 +00:00
init_img_inpaint ,
init_mask_inpaint ,
2022-09-09 16:43:16 +00:00
] ,
)
2022-09-03 09:08:45 +00:00
img2img_args = dict (
2022-10-02 12:03:39 +00:00
fn = wrap_gradio_gpu_call ( modules . img2img . img2img ) ,
2022-09-22 09:11:48 +00:00
_js = " submit_img2img " ,
2022-09-03 09:08:45 +00:00
inputs = [
2022-09-22 09:11:48 +00:00
dummy_component ,
2022-09-09 20:16:02 +00:00
img2img_prompt ,
2022-09-11 14:35:12 +00:00
img2img_negative_prompt ,
2022-09-09 20:16:02 +00:00
img2img_prompt_style ,
2022-09-14 14:56:21 +00:00
img2img_prompt_style2 ,
2022-09-03 09:08:45 +00:00
init_img ,
init_img_with_mask ,
2022-09-22 09:11:48 +00:00
init_img_inpaint ,
init_mask_inpaint ,
2022-09-09 16:43:16 +00:00
mask_mode ,
2022-09-03 09:08:45 +00:00
steps ,
sampler_index ,
mask_blur ,
inpainting_fill ,
2022-09-07 09:32:28 +00:00
restore_faces ,
2022-09-05 00:25:37 +00:00
tiling ,
2022-09-03 09:08:45 +00:00
batch_count ,
batch_size ,
cfg_scale ,
denoising_strength ,
seed ,
2022-09-21 10:34:10 +00:00
subseed , subseed_strength , seed_resize_from_h , seed_resize_from_w , seed_checkbox ,
2022-09-03 09:08:45 +00:00
height ,
width ,
resize_mode ,
inpaint_full_res ,
2022-09-22 09:11:48 +00:00
inpaint_full_res_padding ,
2022-09-03 18:02:38 +00:00
inpainting_mask_invert ,
2022-09-22 09:11:48 +00:00
img2img_batch_input_dir ,
img2img_batch_output_dir ,
2022-09-03 14:21:15 +00:00
] + custom_inputs ,
2022-09-03 09:08:45 +00:00
outputs = [
img2img_gallery ,
generation_info ,
html_info
2022-09-18 08:14:42 +00:00
] ,
show_progress = False ,
2022-09-03 09:08:45 +00:00
)
2022-09-09 20:16:02 +00:00
img2img_prompt . submit ( * * img2img_args )
2022-09-03 09:08:45 +00:00
submit . click ( * * img2img_args )
2022-09-11 15:48:36 +00:00
img2img_interrogate . click (
fn = interrogate ,
inputs = [ init_img ] ,
outputs = [ img2img_prompt ] ,
)
2022-10-08 16:02:56 +00:00
if cmd_opts . deepdanbooru :
img2img_deepbooru . click (
fn = interrogate_deepbooru ,
inputs = [ init_img ] ,
outputs = [ img2img_prompt ] ,
)
2022-10-05 18:50:10 +00:00
2022-09-03 09:08:45 +00:00
save . click (
fn = wrap_gradio_call ( save_files ) ,
2022-10-08 05:09:29 +00:00
_js = " (x, y, z, w) => [x, y, z, selected_gallery_index()] " ,
2022-09-03 09:08:45 +00:00
inputs = [
generation_info ,
img2img_gallery ,
2022-10-08 05:09:29 +00:00
do_make_zip ,
html_info ,
2022-09-03 09:08:45 +00:00
] ,
outputs = [
2022-10-08 05:09:29 +00:00
download_files ,
2022-09-03 09:08:45 +00:00
html_info ,
html_info ,
html_info ,
]
)
2022-09-14 14:56:21 +00:00
roll . click (
fn = roll_artist ,
2022-09-30 16:12:44 +00:00
_js = " update_img2img_tokens " ,
2022-09-14 14:56:21 +00:00
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-30 16:12:44 +00:00
style_js_funcs = [ " update_txt2img_tokens " , " update_img2img_tokens " ]
2022-09-14 14:56:21 +00:00
for button , ( prompt , negative_prompt ) in zip ( [ txt2img_save_style , img2img_save_style ] , prompts ) :
2022-09-09 20:16:02 +00:00
button . click (
fn = add_style ,
_js = " ask_for_style_name " ,
2022-09-11 14:35:12 +00: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 14:56:21 +00:00
outputs = [ txt2img_prompt_style , img2img_prompt_style , txt2img_prompt_style2 , img2img_prompt_style2 ] ,
)
2022-09-29 18:40:47 +00:00
for button , ( prompt , negative_prompt ) , ( style1 , style2 ) , js_func in zip ( [ txt2img_prompt_style_apply , img2img_prompt_style_apply ] , prompts , style_dropdowns , style_js_funcs ) :
2022-09-14 14:56:21 +00:00
button . click (
fn = apply_styles ,
2022-09-29 18:40:47 +00:00
_js = js_func ,
2022-09-14 14:56:21 +00:00
inputs = [ prompt , negative_prompt , style1 , style2 ] ,
outputs = [ prompt , negative_prompt , style1 , style2 ] ,
2022-09-09 20:16:02 +00:00
)
2022-09-25 06:25:28 +00:00
img2img_paste_fields = [
( img2img_prompt , " Prompt " ) ,
( img2img_negative_prompt , " Negative prompt " ) ,
( steps , " Steps " ) ,
( sampler_index , " Sampler " ) ,
( restore_faces , " Face restoration " ) ,
( cfg_scale , " CFG scale " ) ,
( seed , " Seed " ) ,
( width , " Size-1 " ) ,
( height , " Size-2 " ) ,
( batch_size , " Batch size " ) ,
( subseed , " Variation seed " ) ,
( subseed_strength , " Variation seed strength " ) ,
( seed_resize_from_w , " Seed resize from-1 " ) ,
( seed_resize_from_h , " Seed resize from-2 " ) ,
( denoising_strength , " Denoising strength " ) ,
]
2022-09-29 19:47:06 +00:00
token_button . click ( fn = update_token_counter , inputs = [ img2img_prompt , steps ] , outputs = [ token_counter ] )
2022-09-23 19:49:21 +00:00
2022-09-03 09:08:45 +00:00
with gr . Blocks ( analytics_enabled = False ) as extras_interface :
with gr . Row ( ) . style ( equal_height = False ) :
with gr . Column ( variant = ' panel ' ) :
2022-09-22 09:11:48 +00:00
with gr . Tabs ( elem_id = " mode_extras " ) :
2022-09-16 03:23:37 +00:00
with gr . TabItem ( ' Single Image ' ) :
2022-09-23 19:49:21 +00:00
extras_image = gr . Image ( label = " Source " , source = " upload " , interactive = True , type = " pil " )
2022-09-16 03:23:37 +00:00
with gr . TabItem ( ' Batch Process ' ) :
2022-09-16 07:21:59 +00:00
image_batch = gr . File ( label = " Batch Process " , file_count = " multiple " , interactive = True , type = " file " )
2022-09-04 15:54:12 +00:00
2022-10-16 04:50:55 +00:00
with gr . TabItem ( ' Batch from Directory ' ) :
extras_batch_input_dir = gr . Textbox ( label = " Input directory " , * * shared . hide_dirs ,
placeholder = " A directory on the same machine where the server is running. "
)
extras_batch_output_dir = gr . Textbox ( label = " Output directory " , * * shared . hide_dirs ,
placeholder = " Leave blank to save images to the default path. "
)
show_extras_results = gr . Checkbox ( label = ' Show result images ' , value = True )
2022-10-10 01:26:52 +00:00
with gr . Tabs ( elem_id = " extras_resize_mode " ) :
with gr . TabItem ( ' Scale by ' ) :
upscaling_resize = gr . Slider ( minimum = 1.0 , maximum = 4.0 , step = 0.05 , label = " Resize " , value = 2 )
with gr . TabItem ( ' Scale to ' ) :
with gr . Group ( ) :
with gr . Row ( ) :
2022-10-10 18:04:21 +00:00
upscaling_resize_w = gr . Number ( label = " Width " , value = 512 , precision = 0 )
upscaling_resize_h = gr . Number ( label = " Height " , value = 512 , precision = 0 )
2022-10-10 01:26:52 +00:00
upscaling_crop = gr . Checkbox ( label = ' Crop to fit ' , value = True )
2022-09-04 15:54:12 +00:00
with gr . Group ( ) :
2022-10-17 18:15:32 +00:00
extras_upscaler_1 = gr . Radio ( label = ' Upscaler 1 ' , elem_id = " extras_upscaler_1 " , choices = [ x . name for x in shared . sd_upscalers ] , value = shared . sd_upscalers [ 0 ] . name , type = " index " )
2022-09-04 15:54:12 +00:00
with gr . Group ( ) :
2022-10-18 05:15:38 +00:00
extras_upscaler_2 = gr . Radio ( label = ' Upscaler 2 ' , elem_id = " extras_upscaler_2 " , choices = [ x . name for x in shared . sd_upscalers ] , value = shared . sd_upscalers [ 0 ] . name , type = " index " )
2022-09-04 15:54:12 +00:00
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 10:35:02 +00: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 10:46:08 +00: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 09:08:45 +00:00
submit = gr . Button ( ' Generate ' , elem_id = " extras_generate " , variant = ' primary ' )
with gr . Column ( variant = ' panel ' ) :
2022-09-22 09:30:11 +00:00
result_images = gr . Gallery ( label = " Result " , show_label = False )
2022-09-03 09:08:45 +00:00
html_info_x = gr . HTML ( )
html_info = gr . HTML ( )
2022-09-23 03:40:39 +00:00
extras_send_to_img2img = gr . Button ( ' Send to img2img ' )
2022-09-23 11:17:23 +00:00
extras_send_to_inpaint = gr . Button ( ' Send to inpaint ' )
2022-09-28 08:40:05 +00:00
button_id = " hidden_element " if shared . cmd_opts . hide_ui_dir_config else ' '
2022-09-28 08:31:53 +00:00
open_extras_folder = gr . Button ( ' Open output directory ' , elem_id = button_id )
2022-09-03 09:08:45 +00:00
2022-10-12 23:17:26 +00:00
2022-09-22 09:11:48 +00:00
submit . click (
2022-10-02 12:03:39 +00:00
fn = wrap_gradio_gpu_call ( modules . extras . run_extras ) ,
2022-09-22 09:11:48 +00:00
_js = " get_extras_tab_index " ,
2022-09-03 09:08:45 +00:00
inputs = [
2022-10-10 01:26:52 +00:00
dummy_component ,
2022-09-22 09:11:48 +00:00
dummy_component ,
2022-09-23 19:49:21 +00:00
extras_image ,
2022-09-16 03:23:37 +00:00
image_batch ,
2022-10-16 04:50:55 +00:00
extras_batch_input_dir ,
extras_batch_output_dir ,
show_extras_results ,
2022-09-07 10:35:02 +00:00
gfpgan_visibility ,
codeformer_visibility ,
codeformer_weight ,
2022-09-04 15:54:12 +00:00
upscaling_resize ,
2022-10-10 01:26:52 +00:00
upscaling_resize_w ,
upscaling_resize_h ,
upscaling_crop ,
2022-09-04 15:54:12 +00:00
extras_upscaler_1 ,
extras_upscaler_2 ,
extras_upscaler_2_visibility ,
2022-09-03 09:08:45 +00:00
] ,
outputs = [
2022-09-16 03:23:37 +00:00
result_images ,
2022-09-03 09:08:45 +00:00
html_info_x ,
html_info ,
]
)
2022-10-10 01:26:52 +00:00
2022-09-23 03:40:39 +00:00
extras_send_to_img2img . click (
fn = lambda x : image_from_url_text ( x ) ,
_js = " extract_image_from_gallery_img2img " ,
inputs = [ result_images ] ,
outputs = [ init_img ] ,
)
2022-10-10 01:26:52 +00:00
2022-09-23 11:17:23 +00:00
extras_send_to_inpaint . click (
fn = lambda x : image_from_url_text ( x ) ,
2022-10-10 15:46:48 +00:00
_js = " extract_image_from_gallery_inpaint " ,
2022-09-23 11:17:23 +00:00
inputs = [ result_images ] ,
outputs = [ init_img_with_mask ] ,
)
2022-09-03 09:08:45 +00:00
2022-09-23 19:49:21 +00:00
with gr . Blocks ( analytics_enabled = False ) as pnginfo_interface :
with gr . Row ( ) . style ( equal_height = False ) :
with gr . Column ( variant = ' panel ' ) :
image = gr . Image ( elem_id = " pnginfo_image " , label = " Source " , source = " upload " , interactive = True , type = " pil " )
with gr . Column ( variant = ' panel ' ) :
html = gr . HTML ( )
generation_info = gr . Textbox ( visible = False )
html2 = gr . HTML ( )
with gr . Row ( ) :
pnginfo_send_to_txt2img = gr . Button ( ' Send to txt2img ' )
pnginfo_send_to_img2img = gr . Button ( ' Send to img2img ' )
image . change (
2022-10-02 12:03:39 +00:00
fn = wrap_gradio_call ( modules . extras . run_pnginfo ) ,
2022-09-23 19:49:21 +00:00
inputs = [ image ] ,
outputs = [ html , generation_info , html2 ] ,
)
2022-10-12 16:19:34 +00:00
#images history
images_history_switch_dict = {
" fn " : modules . generation_parameters_copypaste . connect_paste ,
" t2i " : txt2img_paste_fields ,
" i2i " : img2img_paste_fields
}
2022-10-14 20:17:28 +00:00
2022-10-14 21:43:15 +00:00
images_history = img_his . create_history_tabs ( gr , opts , wrap_gradio_call ( modules . extras . run_pnginfo ) , images_history_switch_dict )
2022-09-03 09:08:45 +00:00
2022-09-25 23:22:12 +00:00
with gr . Blocks ( ) as modelmerger_interface :
with gr . Row ( ) . style ( equal_height = False ) :
with gr . Column ( variant = ' panel ' ) :
2022-09-28 22:00:48 +00:00
gr . HTML ( value = " <p>A merger of the two checkpoints will be generated in your <b>checkpoint</b> directory.</p> " )
2022-10-02 12:03:39 +00:00
2022-09-27 19:21:25 +00:00
with gr . Row ( ) :
2022-10-14 06:05:06 +00:00
primary_model_name = gr . Dropdown ( modules . sd_models . checkpoint_tiles ( ) , elem_id = " modelmerger_primary_model_name " , label = " Primary model (A) " )
secondary_model_name = gr . Dropdown ( modules . sd_models . checkpoint_tiles ( ) , elem_id = " modelmerger_secondary_model_name " , label = " Secondary model (B) " )
tertiary_model_name = gr . Dropdown ( modules . sd_models . checkpoint_tiles ( ) , elem_id = " modelmerger_tertiary_model_name " , label = " Tertiary model (C) " )
2022-09-28 23:50:34 +00:00
custom_name = gr . Textbox ( label = " Custom Name (Optional) " )
2022-10-14 19:01:49 +00:00
interp_amount = gr . Slider ( minimum = 0.0 , maximum = 1.0 , step = 0.05 , label = ' Multiplier (M) - set to 0 to get model A ' , value = 0.3 )
interp_method = gr . Radio ( choices = [ " Weighted sum " , " Add difference " ] , value = " Weighted sum " , label = " Interpolation Method " )
2022-10-08 13:48:15 +00:00
save_as_half = gr . Checkbox ( value = False , label = " Save as float16 " )
2022-09-28 21:59:44 +00:00
modelmerger_merge = gr . Button ( elem_id = " modelmerger_merge " , label = " Merge " , variant = ' primary ' )
2022-10-02 12:03:39 +00:00
2022-09-25 23:22:12 +00:00
with gr . Column ( variant = ' panel ' ) :
2022-09-27 07:44:00 +00:00
submit_result = gr . Textbox ( elem_id = " modelmerger_result " , show_label = False )
2022-09-25 23:22:12 +00:00
2022-10-02 12:03:39 +00:00
sd_hijack . model_hijack . embedding_db . load_textual_inversion_embeddings ( )
2022-10-12 08:05:57 +00:00
with gr . Blocks ( ) as train_interface :
2022-10-02 12:03:39 +00:00
with gr . Row ( ) . style ( equal_height = False ) :
2022-10-12 08:05:57 +00:00
gr . HTML ( value = " <p style= ' margin-bottom: 0.7em ' >See <b><a href= \" https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Textual-Inversion \" >wiki</a></b> for detailed explanation.</p> " )
2022-10-02 19:41:21 +00:00
2022-10-12 08:05:57 +00:00
with gr . Row ( ) . style ( equal_height = False ) :
with gr . Tabs ( elem_id = " train_tabs " ) :
2022-10-02 12:03:39 +00:00
2022-10-12 08:05:57 +00:00
with gr . Tab ( label = " Create embedding " ) :
2022-10-02 12:03:39 +00:00
new_embedding_name = gr . Textbox ( label = " Name " )
2022-10-02 16:40:51 +00:00
initialization_text = gr . Textbox ( label = " Initialization text " , value = " * " )
2022-10-02 12:03:39 +00:00
nvpt = gr . Slider ( label = " Number of vectors per token " , minimum = 1 , maximum = 75 , step = 1 , value = 1 )
with gr . Row ( ) :
with gr . Column ( scale = 3 ) :
gr . HTML ( value = " " )
with gr . Column ( ) :
2022-10-11 11:53:02 +00:00
create_embedding = gr . Button ( value = " Create embedding " , variant = ' primary ' )
2022-10-02 12:03:39 +00:00
2022-10-12 08:05:57 +00:00
with gr . Tab ( label = " Create hypernetwork " ) :
2022-10-07 20:22:22 +00:00
new_hypernetwork_name = gr . Textbox ( label = " Name " )
2022-10-11 15:04:47 +00:00
new_hypernetwork_sizes = gr . CheckboxGroup ( label = " Modules " , value = [ " 768 " , " 320 " , " 640 " , " 1280 " ] , choices = [ " 768 " , " 320 " , " 640 " , " 1280 " ] )
2022-10-19 15:28:42 +00:00
new_hypernetwork_layer_structure = gr . Textbox ( " 1, 2, 1 " , label = " Enter hypernetwork layer structure " , placeholder = " 1st and last digit must be 1. ex: ' 1, 2, 1 ' " )
2022-10-19 14:30:33 +00:00
new_hypernetwork_add_layer_norm = gr . Checkbox ( label = " Add layer normalization " )
2022-10-07 20:22:22 +00:00
with gr . Row ( ) :
with gr . Column ( scale = 3 ) :
gr . HTML ( value = " " )
with gr . Column ( ) :
2022-10-11 11:53:02 +00:00
create_hypernetwork = gr . Button ( value = " Create hypernetwork " , variant = ' primary ' )
2022-10-02 12:03:39 +00:00
2022-10-12 08:05:57 +00:00
with gr . Tab ( label = " Preprocess images " ) :
2022-10-02 19:41:21 +00:00
process_src = gr . Textbox ( label = ' Source directory ' )
process_dst = gr . Textbox ( label = ' Destination directory ' )
2022-10-10 13:35:35 +00:00
process_width = gr . Slider ( minimum = 64 , maximum = 2048 , step = 64 , label = " Width " , value = 512 )
process_height = gr . Slider ( minimum = 64 , maximum = 2048 , step = 64 , label = " Height " , value = 512 )
2022-10-02 19:41:21 +00:00
with gr . Row ( ) :
2022-10-08 16:50:01 +00:00
process_flip = gr . Checkbox ( label = ' Create flipped copies ' )
process_split = gr . Checkbox ( label = ' Split oversized images into two ' )
2022-10-12 18:55:43 +00:00
process_caption = gr . Checkbox ( label = ' Use BLIP for caption ' )
process_caption_deepbooru = gr . Checkbox ( label = ' Use deepbooru for caption ' , visible = True if cmd_opts . deepdanbooru else False )
2022-10-02 19:41:21 +00:00
with gr . Row ( ) :
with gr . Column ( scale = 3 ) :
gr . HTML ( value = " " )
with gr . Column ( ) :
run_preprocess = gr . Button ( value = " Preprocess " , variant = ' primary ' )
2022-10-12 08:05:57 +00:00
with gr . Tab ( label = " Train " ) :
2022-10-10 08:07:46 +00:00
gr . HTML ( value = " <p style= ' margin-bottom: 0.7em ' >Train an embedding; must specify a directory with a set of 1:1 ratio images</p> " )
2022-10-16 04:42:52 +00:00
with gr . Row ( ) :
2022-10-17 18:15:32 +00:00
train_embedding_name = gr . Dropdown ( label = ' Embedding ' , elem_id = " train_embedding " , choices = sorted ( sd_hijack . model_hijack . embedding_db . word_embeddings . keys ( ) ) )
2022-10-16 04:42:52 +00:00
create_refresh_button ( train_embedding_name , sd_hijack . model_hijack . embedding_db . load_textual_inversion_embeddings , lambda : { " choices " : sorted ( sd_hijack . model_hijack . embedding_db . word_embeddings . keys ( ) ) } , " refresh_train_embedding_name " )
with gr . Row ( ) :
2022-10-17 18:15:32 +00:00
train_hypernetwork_name = gr . Dropdown ( label = ' Hypernetwork ' , elem_id = " train_hypernetwork " , choices = [ x for x in shared . hypernetworks . keys ( ) ] )
2022-10-16 04:42:52 +00:00
create_refresh_button ( train_hypernetwork_name , shared . reload_hypernetworks , lambda : { " choices " : sorted ( [ x for x in shared . hypernetworks . keys ( ) ] ) } , " refresh_train_hypernetwork_name " )
2022-10-11 19:03:05 +00:00
learn_rate = gr . Textbox ( label = ' Learning rate ' , placeholder = " Learning rate " , value = " 0.005 " )
2022-10-15 06:24:59 +00:00
batch_size = gr . Number ( label = ' Batch size ' , value = 1 , precision = 0 )
2022-10-02 12:03:39 +00:00
dataset_directory = gr . Textbox ( label = ' Dataset directory ' , placeholder = " Path to directory with input images " )
log_directory = gr . Textbox ( label = ' Log directory ' , placeholder = " Path to directory where to write outputs " , value = " textual_inversion " )
template_file = gr . Textbox ( label = ' Prompt template file ' , value = os . path . join ( script_path , " textual_inversion_templates " , " style_filewords.txt " ) )
2022-10-10 13:35:35 +00:00
training_width = gr . Slider ( minimum = 64 , maximum = 2048 , step = 64 , label = " Width " , value = 512 )
training_height = gr . Slider ( minimum = 64 , maximum = 2048 , step = 64 , label = " Height " , value = 512 )
2022-10-02 12:03:39 +00:00
steps = gr . Number ( label = ' Max steps ' , value = 100000 , precision = 0 )
2022-10-02 19:59:01 +00:00
create_image_every = gr . Number ( label = ' Save an image to log directory every N steps, 0 to disable ' , value = 500 , precision = 0 )
save_embedding_every = gr . Number ( label = ' Save a copy of embedding to log directory every N steps, 0 to disable ' , value = 500 , precision = 0 )
2022-10-09 04:40:57 +00:00
save_image_with_stored_embedding = gr . Checkbox ( label = ' Save images with embedding in PNG chunks ' , value = True )
2022-10-14 17:31:49 +00:00
preview_from_txt2img = gr . Checkbox ( label = ' Read parameters (prompt, etc...) from txt2img tab when making previews ' , value = False )
2022-10-02 12:03:39 +00:00
with gr . Row ( ) :
2022-10-07 20:22:22 +00:00
interrupt_training = gr . Button ( value = " Interrupt " )
train_hypernetwork = gr . Button ( value = " Train Hypernetwork " , variant = ' primary ' )
train_embedding = gr . Button ( value = " Train Embedding " , variant = ' primary ' )
2022-10-02 12:03:39 +00:00
with gr . Column ( ) :
progressbar = gr . HTML ( elem_id = " ti_progressbar " )
ti_output = gr . Text ( elem_id = " ti_output " , value = " " , show_label = False )
ti_gallery = gr . Gallery ( label = ' Output ' , show_label = False , elem_id = ' ti_gallery ' ) . style ( grid = 4 )
ti_preview = gr . Image ( elem_id = ' ti_preview ' , visible = False )
ti_progress = gr . HTML ( elem_id = " ti_progress " , value = " " )
ti_outcome = gr . HTML ( elem_id = " ti_error " , value = " " )
setup_progressbar ( progressbar , ti_preview , ' ti ' , textinfo = ti_progress )
create_embedding . click (
fn = modules . textual_inversion . ui . create_embedding ,
inputs = [
new_embedding_name ,
2022-10-02 16:40:51 +00:00
initialization_text ,
2022-10-02 12:03:39 +00:00
nvpt ,
] ,
outputs = [
train_embedding_name ,
ti_output ,
ti_outcome ,
]
)
2022-10-07 20:22:22 +00:00
create_hypernetwork . click (
2022-10-11 12:54:34 +00:00
fn = modules . hypernetworks . ui . create_hypernetwork ,
2022-10-07 20:22:22 +00:00
inputs = [
new_hypernetwork_name ,
2022-10-11 15:04:47 +00:00
new_hypernetwork_sizes ,
2022-10-19 14:30:33 +00:00
new_hypernetwork_layer_structure ,
new_hypernetwork_add_layer_norm ,
2022-10-07 20:22:22 +00:00
] ,
outputs = [
train_hypernetwork_name ,
ti_output ,
ti_outcome ,
]
)
2022-10-02 19:41:21 +00:00
run_preprocess . click (
fn = wrap_gradio_gpu_call ( modules . textual_inversion . ui . preprocess , extra_outputs = [ gr . update ( ) ] ) ,
_js = " start_training_textual_inversion " ,
inputs = [
process_src ,
process_dst ,
2022-10-10 13:35:35 +00:00
process_width ,
process_height ,
2022-10-02 19:41:21 +00:00
process_flip ,
process_split ,
process_caption ,
2022-10-10 08:34:00 +00:00
process_caption_deepbooru
2022-10-02 19:41:21 +00:00
] ,
outputs = [
ti_output ,
ti_outcome ,
] ,
)
2022-10-02 12:03:39 +00:00
train_embedding . click (
fn = wrap_gradio_gpu_call ( modules . textual_inversion . ui . train_embedding , extra_outputs = [ gr . update ( ) ] ) ,
_js = " start_training_textual_inversion " ,
inputs = [
train_embedding_name ,
learn_rate ,
2022-10-15 06:24:59 +00:00
batch_size ,
2022-10-02 12:03:39 +00:00
dataset_directory ,
log_directory ,
2022-10-10 13:35:35 +00:00
training_width ,
training_height ,
2022-10-02 12:03:39 +00:00
steps ,
create_image_every ,
save_embedding_every ,
template_file ,
2022-10-09 04:40:57 +00:00
save_image_with_stored_embedding ,
2022-10-14 17:31:49 +00:00
preview_from_txt2img ,
* txt2img_preview_params ,
2022-10-02 12:03:39 +00:00
] ,
outputs = [
ti_output ,
ti_outcome ,
]
)
2022-10-07 20:22:22 +00:00
train_hypernetwork . click (
2022-10-11 12:54:34 +00:00
fn = wrap_gradio_gpu_call ( modules . hypernetworks . ui . train_hypernetwork , extra_outputs = [ gr . update ( ) ] ) ,
2022-10-07 20:22:22 +00:00
_js = " start_training_textual_inversion " ,
inputs = [
train_hypernetwork_name ,
learn_rate ,
2022-10-15 06:24:59 +00:00
batch_size ,
2022-10-07 20:22:22 +00:00
dataset_directory ,
log_directory ,
2022-10-19 05:44:33 +00:00
training_width ,
training_height ,
2022-10-02 12:03:39 +00:00
steps ,
create_image_every ,
save_embedding_every ,
template_file ,
2022-10-14 17:31:49 +00:00
preview_from_txt2img ,
* txt2img_preview_params ,
2022-10-02 12:03:39 +00:00
] ,
outputs = [
ti_output ,
ti_outcome ,
]
)
interrupt_training . click (
fn = lambda : shared . state . interrupt ( ) ,
inputs = [ ] ,
outputs = [ ] ,
)
2022-10-13 16:22:41 +00:00
def create_setting_component ( key , is_quicksettings = False ) :
2022-09-03 09:08:45 +00:00
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 20:00:42 +00:00
args = info . component_args ( ) if callable ( info . component_args ) else info . component_args
2022-09-03 09:08:45 +00:00
if info . component is not None :
2022-09-11 20:00:42 +00:00
comp = info . component
2022-09-03 09:08:45 +00:00
elif t == str :
2022-09-11 20:00:42 +00:00
comp = gr . Textbox
2022-09-03 09:08:45 +00:00
elif t == int :
2022-09-11 20:00:42 +00:00
comp = gr . Number
2022-09-03 09:08:45 +00:00
elif t == bool :
2022-09-11 20:00:42 +00:00
comp = gr . Checkbox
2022-09-03 09:08:45 +00:00
else :
raise Exception ( f ' bad options item type: { str ( t ) } for key { key } ' )
2022-10-17 18:15:32 +00:00
elem_id = " setting_ " + key
2022-10-13 16:22:41 +00:00
if info . refresh is not None :
if is_quicksettings :
2022-10-17 18:15:32 +00:00
res = comp ( label = info . label , value = fun , elem_id = elem_id , * * ( args or { } ) )
create_refresh_button ( res , info . refresh , info . component_args , " refresh_ " + key )
2022-10-13 16:22:41 +00:00
else :
with gr . Row ( variant = " compact " ) :
2022-10-17 18:15:32 +00:00
res = comp ( label = info . label , value = fun , elem_id = elem_id , * * ( args or { } ) )
create_refresh_button ( res , info . refresh , info . component_args , " refresh_ " + key )
2022-10-13 16:22:41 +00:00
else :
2022-10-17 18:15:32 +00:00
res = comp ( label = info . label , value = fun , elem_id = elem_id , * * ( args or { } ) )
2022-10-13 16:22:41 +00:00
return res
2022-09-03 09:08:45 +00:00
2022-09-10 08:10:00 +00:00
components = [ ]
2022-09-28 21:59:44 +00:00
component_dict = { }
2022-09-10 08:10:00 +00:00
2022-09-27 21:02:11 +00:00
def open_folder ( f ) :
2022-10-16 12:59:05 +00:00
if not os . path . exists ( f ) :
2022-10-16 13:03:18 +00:00
print ( f ' Folder " { f } " does not exist. After you create an image, the folder will be created. ' )
2022-10-16 12:59:05 +00:00
return
elif not os . path . isdir ( f ) :
2022-10-09 09:33:37 +00:00
print ( f """
WARNING
An open_folder request was made with an argument that is not a folder .
This could be an error or a malicious attempt to run code on your computer .
Requested path was : { f }
""" , file=sys.stderr)
return
2022-09-28 08:31:53 +00:00
if not shared . cmd_opts . hide_ui_dir_config :
path = os . path . normpath ( f )
if platform . system ( ) == " Windows " :
os . startfile ( path )
elif platform . system ( ) == " Darwin " :
sp . Popen ( [ " open " , path ] )
else :
sp . Popen ( [ " xdg-open " , path ] )
2022-09-27 21:02:11 +00:00
2022-09-03 09:08:45 +00:00
def run_settings ( * args ) :
2022-09-23 14:27:30 +00:00
changed = 0
for key , value , comp in zip ( opts . data_labels . keys ( ) , args , components ) :
2022-10-09 19:24:07 +00:00
if comp != dummy_component and not opts . same_type ( value , opts . data_labels [ key ] . default ) :
return f " Bad value for setting { key } : { value } ; expecting { type ( opts . data_labels [ key ] . default ) . __name__ } " , opts . dumpjson ( )
2022-09-03 09:08:45 +00:00
2022-09-10 08:10:00 +00:00
for key , value , comp in zip ( opts . data_labels . keys ( ) , args , components ) :
2022-10-09 19:24:07 +00:00
if comp == dummy_component :
continue
2022-09-11 20:00:42 +00: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-10-16 17:08:23 +00:00
if cmd_opts . hide_ui_dir_config and key in restricted_opts :
continue
2022-09-17 09:05:04 +00:00
oldval = opts . data . get ( key , None )
2022-09-03 09:08:45 +00:00
opts . data [ key ] = value
2022-09-17 09:05:04 +00:00
2022-09-23 14:27:30 +00:00
if oldval != value :
if opts . data_labels [ key ] . onchange is not None :
opts . data_labels [ key ] . onchange ( )
2022-09-17 09:05:04 +00:00
2022-09-23 14:27:30 +00:00
changed + = 1
2022-09-03 09:08:45 +00:00
opts . save ( shared . config_filename )
2022-09-23 21:13:32 +00:00
return f ' { changed } settings changed. ' , opts . dumpjson ( )
2022-09-03 09:08:45 +00:00
2022-10-09 19:24:07 +00:00
def run_settings_single ( value , key ) :
if not opts . same_type ( value , opts . data_labels [ key ] . default ) :
return gr . update ( visible = True ) , opts . dumpjson ( )
2022-10-16 17:08:23 +00:00
if cmd_opts . hide_ui_dir_config and key in restricted_opts :
return gr . update ( value = oldval ) , opts . dumpjson ( )
2022-10-09 19:24:07 +00:00
oldval = opts . data . get ( key , None )
opts . data [ key ] = value
if oldval != value :
if opts . data_labels [ key ] . onchange is not None :
opts . data_labels [ key ] . onchange ( )
opts . save ( shared . config_filename )
return gr . update ( value = value ) , opts . dumpjson ( )
2022-09-10 08:10:00 +00:00
with gr . Blocks ( analytics_enabled = False ) as settings_interface :
2022-09-18 19:25:18 +00:00
settings_submit = gr . Button ( value = " Apply settings " , variant = ' primary ' )
2022-09-10 08:10:00 +00:00
result = gr . HTML ( )
2022-09-22 18:32:44 +00:00
settings_cols = 3
items_per_col = int ( len ( opts . data_labels ) * 0.9 / settings_cols )
2022-09-10 08:10:00 +00:00
2022-10-13 13:07:18 +00:00
quicksettings_names = [ x . strip ( ) for x in opts . quicksettings . split ( " , " ) ]
quicksettings_names = set ( x for x in quicksettings_names if x != ' quicksettings ' )
2022-10-09 19:24:07 +00:00
quicksettings_list = [ ]
2022-09-22 18:32:44 +00:00
cols_displayed = 0
items_displayed = 0
previous_section = None
column = None
with gr . Row ( elem_id = " settings " ) . style ( equal_height = False ) :
for i , ( k , item ) in enumerate ( opts . data_labels . items ( ) ) :
2022-09-22 16:26:26 +00:00
2022-09-22 18:32:44 +00:00
if previous_section != item . section :
if cols_displayed < settings_cols and ( items_displayed > = items_per_col or previous_section is None ) :
if column is not None :
column . __exit__ ( )
2022-09-22 16:26:26 +00:00
2022-09-22 18:32:44 +00:00
column = gr . Column ( variant = ' panel ' )
column . __enter__ ( )
2022-09-10 08:10:00 +00:00
2022-09-22 18:32:44 +00:00
items_displayed = 0
cols_displayed + = 1
previous_section = item . section
gr . HTML ( elem_id = " settings_header_text_ {} " . format ( item . section [ 0 ] ) , value = ' <h1 class= " gr-button-lg " > {} </h1> ' . format ( item . section [ 1 ] ) )
2022-10-13 13:07:18 +00:00
if k in quicksettings_names :
2022-10-09 19:24:07 +00:00
quicksettings_list . append ( ( i , k , item ) )
components . append ( dummy_component )
else :
component = create_setting_component ( k )
component_dict [ k ] = component
components . append ( component )
items_displayed + = 1
2022-09-03 09:08:45 +00:00
2022-10-13 13:07:18 +00:00
with gr . Row ( ) :
request_notifications = gr . Button ( value = ' Request browser notifications ' , elem_id = " request_notifications " )
2022-10-17 18:15:32 +00:00
download_localization = gr . Button ( value = ' Download localization template ' , elem_id = " download_localization " )
with gr . Row ( ) :
2022-10-13 13:07:18 +00:00
reload_script_bodies = gr . Button ( value = ' Reload custom script bodies (No ui updates, No restart) ' , variant = ' secondary ' )
restart_gradio = gr . Button ( value = ' Restart Gradio and Refresh components (Custom Scripts, ui.py, js and css only) ' , variant = ' primary ' )
2022-09-19 01:41:57 +00:00
request_notifications . click (
fn = lambda : None ,
inputs = [ ] ,
outputs = [ ] ,
2022-09-22 10:15:33 +00:00
_js = ' function() {} '
2022-09-19 01:41:57 +00:00
)
2022-10-17 18:15:32 +00:00
download_localization . click (
fn = lambda : None ,
inputs = [ ] ,
outputs = [ ] ,
_js = ' download_localization '
)
2022-10-02 00:19:55 +00:00
def reload_scripts ( ) :
2022-10-02 18:26:06 +00:00
modules . scripts . reload_script_body_only ( )
2022-10-14 17:04:47 +00:00
reload_javascript ( ) # need to refresh the html page
2022-10-02 00:19:55 +00:00
reload_script_bodies . click (
fn = reload_scripts ,
inputs = [ ] ,
outputs = [ ] ,
_js = ' function() {} '
)
2022-10-02 00:36:30 +00:00
def request_restart ( ) :
2022-10-05 03:43:05 +00:00
shared . state . interrupt ( )
2022-10-02 18:26:06 +00:00
settings_interface . gradio_ref . do_restart = True
2022-10-02 00:36:30 +00:00
restart_gradio . click (
fn = request_restart ,
inputs = [ ] ,
outputs = [ ] ,
_js = ' function() { restart_reload()} '
)
2022-10-10 01:26:52 +00:00
2022-09-22 18:32:44 +00:00
if column is not None :
column . __exit__ ( )
2022-09-03 09:08:45 +00:00
interfaces = [
2022-09-10 08:10:00 +00:00
( txt2img_interface , " txt2img " , " txt2img " ) ,
( img2img_interface , " img2img " , " img2img " ) ,
( extras_interface , " Extras " , " extras " ) ,
( pnginfo_interface , " PNG Info " , " pnginfo " ) ,
2022-10-14 21:43:15 +00:00
( images_history , " History " , " images_history " ) ,
2022-09-25 23:22:12 +00:00
( modelmerger_interface , " Checkpoint Merger " , " modelmerger " ) ,
2022-10-12 08:05:57 +00:00
( train_interface , " Train " , " ti " ) ,
2022-09-10 08:10:00 +00:00
( settings_interface , " Settings " , " settings " ) ,
2022-09-03 09:08:45 +00:00
]
with open ( os . path . join ( script_path , " style.css " ) , " r " , encoding = " utf8 " ) as file :
css = file . read ( )
2022-09-17 13:35:58 +00:00
if os . path . exists ( os . path . join ( script_path , " user.css " ) ) :
2022-09-17 13:28:19 +00:00
with open ( os . path . join ( script_path , " user.css " ) , " r " , encoding = " utf8 " ) as file :
usercss = file . read ( )
css + = usercss
2022-09-03 09:08:45 +00:00
if not cmd_opts . no_progressbar_hiding :
css + = css_hide_progressbar
2022-09-10 08:10:00 +00:00
with gr . Blocks ( css = css , analytics_enabled = False , title = " Stable Diffusion " ) as demo :
2022-10-09 19:24:07 +00:00
with gr . Row ( elem_id = " quicksettings " ) :
for i , k , item in quicksettings_list :
2022-10-13 16:22:41 +00:00
component = create_setting_component ( k , is_quicksettings = True )
2022-10-09 19:24:07 +00:00
component_dict [ k ] = component
2022-10-01 17:33:31 +00:00
settings_interface . gradio_ref = demo
2022-10-10 01:26:52 +00:00
2022-10-13 17:42:27 +00:00
with gr . Tabs ( elem_id = " tabs " ) as tabs :
2022-09-10 08:10:00 +00:00
for interface , label , ifid in interfaces :
2022-10-11 05:22:46 +00:00
with gr . TabItem ( label , id = ifid , elem_id = ' tab_ ' + ifid ) :
2022-09-10 08:10:00 +00:00
interface . render ( )
2022-10-10 01:26:52 +00:00
2022-09-26 20:57:31 +00:00
if os . path . exists ( os . path . join ( script_path , " notification.mp3 " ) ) :
audio_notification = gr . Audio ( interactive = False , value = os . path . join ( script_path , " notification.mp3 " ) , elem_id = " audio_notification " , visible = False )
2022-09-10 08:10:00 +00:00
2022-09-19 14:16:04 +00:00
text_settings = gr . Textbox ( elem_id = " settings_json " , value = lambda : opts . dumpjson ( ) , visible = False )
2022-09-18 19:25:18 +00:00
settings_submit . click (
2022-09-23 21:13:32 +00:00
fn = run_settings ,
inputs = components ,
outputs = [ result , text_settings ] ,
2022-09-18 19:25:18 +00:00
)
2022-10-09 19:24:07 +00:00
for i , k , item in quicksettings_list :
component = component_dict [ k ]
component . change (
fn = lambda value , k = k : run_settings_single ( value , key = k ) ,
inputs = [ component ] ,
outputs = [ component , text_settings ] ,
)
2022-09-28 23:50:34 +00:00
def modelmerger ( * args ) :
try :
2022-10-02 12:03:39 +00:00
results = modules . extras . run_modelmerger ( * args )
2022-09-28 23:50:34 +00:00
except Exception as e :
print ( " Error loading/saving model file: " , file = sys . stderr )
print ( traceback . format_exc ( ) , file = sys . stderr )
2022-10-02 12:03:39 +00:00
modules . sd_models . list_models ( ) # to remove the potentially missing models from the list
2022-09-28 23:50:34 +00:00
return [ " Error loading/saving model file. It doesn ' t exist or the name contains illegal characters " ] + [ gr . Dropdown . update ( choices = modules . sd_models . checkpoint_tiles ( ) ) for _ in range ( 3 ) ]
return results
2022-09-18 19:25:18 +00:00
2022-09-28 21:59:44 +00:00
modelmerger_merge . click (
2022-09-28 23:50:34 +00:00
fn = modelmerger ,
2022-09-28 21:59:44 +00:00
inputs = [
primary_model_name ,
secondary_model_name ,
2022-10-14 06:05:06 +00:00
tertiary_model_name ,
2022-09-28 21:59:44 +00:00
interp_method ,
interp_amount ,
save_as_half ,
2022-09-28 23:50:34 +00:00
custom_name ,
2022-09-28 21:59:44 +00:00
] ,
outputs = [
submit_result ,
primary_model_name ,
secondary_model_name ,
2022-10-14 06:05:06 +00:00
tertiary_model_name ,
2022-09-28 21:59:44 +00:00
component_dict [ ' sd_model_checkpoint ' ] ,
]
)
2022-09-25 20:09:43 +00:00
paste_field_names = [ ' Prompt ' , ' Negative prompt ' , ' Steps ' , ' Face restoration ' , ' Seed ' , ' Size-1 ' , ' Size-2 ' ]
txt2img_fields = [ field for field , name in txt2img_paste_fields if name in paste_field_names ]
img2img_fields = [ field for field , name in img2img_paste_fields if name in paste_field_names ]
2022-09-10 08:10:00 +00:00
send_to_img2img . click (
2022-09-25 20:09:43 +00:00
fn = lambda img , * args : ( image_from_url_text ( img ) , * args ) ,
_js = " (gallery, ...args) => [extract_image_from_gallery_img2img(gallery), ...args] " ,
inputs = [ txt2img_gallery ] + txt2img_fields ,
outputs = [ init_img ] + img2img_fields ,
2022-09-10 08:10:00 +00:00
)
send_to_inpaint . click (
2022-09-25 20:09:43 +00:00
fn = lambda x , * args : ( image_from_url_text ( x ) , * args ) ,
_js = " (gallery, ...args) => [extract_image_from_gallery_inpaint(gallery), ...args] " ,
inputs = [ txt2img_gallery ] + txt2img_fields ,
outputs = [ init_img_with_mask ] + img2img_fields ,
2022-09-10 08:10:00 +00:00
)
img2img_send_to_img2img . click (
fn = lambda x : image_from_url_text ( x ) ,
2022-09-23 19:49:21 +00:00
_js = " extract_image_from_gallery_img2img " ,
2022-09-10 08:10:00 +00:00
inputs = [ img2img_gallery ] ,
outputs = [ init_img ] ,
)
img2img_send_to_inpaint . click (
fn = lambda x : image_from_url_text ( x ) ,
2022-09-23 19:49:21 +00:00
_js = " extract_image_from_gallery_inpaint " ,
2022-09-10 08:10:00 +00:00
inputs = [ img2img_gallery ] ,
outputs = [ init_img_with_mask ] ,
)
send_to_extras . click (
fn = lambda x : image_from_url_text ( x ) ,
2022-09-10 21:21:47 +00:00
_js = " extract_image_from_gallery_extras " ,
2022-09-10 08:10:00 +00:00
inputs = [ txt2img_gallery ] ,
2022-09-23 19:49:21 +00:00
outputs = [ extras_image ] ,
2022-09-10 08:10:00 +00:00
)
2022-09-27 21:02:11 +00:00
open_txt2img_folder . click (
fn = lambda : open_folder ( opts . outdir_samples or opts . outdir_txt2img_samples ) ,
inputs = [ ] ,
outputs = [ ] ,
)
open_img2img_folder . click (
fn = lambda : open_folder ( opts . outdir_samples or opts . outdir_img2img_samples ) ,
inputs = [ ] ,
outputs = [ ] ,
)
open_extras_folder . click (
fn = lambda : open_folder ( opts . outdir_samples or opts . outdir_extras_samples ) ,
inputs = [ ] ,
outputs = [ ] ,
)
2022-09-10 08:10:00 +00:00
img2img_send_to_extras . click (
fn = lambda x : image_from_url_text ( x ) ,
2022-09-10 21:21:47 +00:00
_js = " extract_image_from_gallery_extras " ,
2022-09-10 08:10:00 +00:00
inputs = [ img2img_gallery ] ,
2022-09-23 19:49:21 +00:00
outputs = [ extras_image ] ,
2022-09-10 08:10:00 +00:00
)
2022-09-03 09:08:45 +00:00
2022-10-14 16:30:28 +00:00
settings_map = {
' sd_hypernetwork ' : ' Hypernet ' ,
' CLIP_stop_at_last_layers ' : ' Clip skip ' ,
' sd_model_checkpoint ' : ' Model hash ' ,
}
settings_paste_fields = [
( component_dict [ k ] , lambda d , k = k , v = v : apply_setting ( k , d . get ( v , None ) ) )
for k , v in settings_map . items ( )
]
modules . generation_parameters_copypaste . connect_paste ( txt2img_paste , txt2img_paste_fields + settings_paste_fields , txt2img_prompt )
modules . generation_parameters_copypaste . connect_paste ( img2img_paste , img2img_paste_fields + settings_paste_fields , img2img_prompt )
modules . generation_parameters_copypaste . connect_paste ( pnginfo_send_to_txt2img , txt2img_paste_fields + settings_paste_fields , generation_info , ' switch_to_txt2img ' )
modules . generation_parameters_copypaste . connect_paste ( pnginfo_send_to_img2img , img2img_paste_fields + settings_paste_fields , generation_info , ' switch_to_img2img_img2img ' )
2022-09-23 19:49:21 +00:00
2022-09-10 05:18:54 +00:00
ui_config_file = cmd_opts . ui_config_file
2022-09-04 10:52:01 +00: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-10-18 09:51:57 +00:00
def apply_field ( obj , field , condition = None , init_field = None ) :
2022-09-04 10:52:01 +00:00
key = path + " / " + field
2022-09-25 05:56:50 +00:00
if getattr ( obj , ' custom_script_source ' , None ) is not None :
key = ' customscript/ ' + obj . custom_script_source + ' / ' + key
2022-10-10 01:26:52 +00:00
2022-09-25 16:43:42 +00:00
if getattr ( obj , ' do_not_save_to_config ' , False ) :
return
2022-10-10 01:26:52 +00:00
2022-09-04 10:52:01 +00:00
saved_value = ui_settings . get ( key , None )
if saved_value is None :
ui_settings [ key ] = getattr ( obj , field )
2022-10-15 20:09:11 +00:00
elif condition and not condition ( saved_value ) :
print ( f ' Warning: Bad ui setting value: { key } : { saved_value } ; Default value " { getattr ( obj , field ) } " will be used instead. ' )
else :
2022-09-04 10:52:01 +00:00
setattr ( obj , field , saved_value )
2022-10-18 09:51:57 +00:00
if init_field is not None :
init_field ( saved_value )
2022-09-04 10:52:01 +00:00
2022-09-25 16:43:42 +00:00
if type ( x ) in [ gr . Slider , gr . Radio , gr . Checkbox , gr . Textbox , gr . Number ] and x . visible :
apply_field ( x , ' visible ' )
2022-09-04 10:52:01 +00:00
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 16:11:29 +00:00
apply_field ( x , ' value ' , lambda val : val in x . choices )
2022-09-04 10:52:01 +00:00
2022-09-25 05:31:02 +00:00
if type ( x ) == gr . Checkbox :
2022-09-25 05:40:37 +00:00
apply_field ( x , ' value ' )
2022-09-25 05:31:02 +00:00
if type ( x ) == gr . Textbox :
2022-09-25 05:40:37 +00:00
apply_field ( x , ' value ' )
2022-10-10 01:26:52 +00:00
2022-09-25 05:39:22 +00:00
if type ( x ) == gr . Number :
2022-09-25 05:40:37 +00:00
apply_field ( x , ' value ' )
2022-10-10 01:26:52 +00:00
2022-10-15 19:47:03 +00:00
# Since there are many dropdowns that shouldn't be saved,
# we only mark dropdowns that should be saved.
if type ( x ) == gr . Dropdown and getattr ( x , ' save_to_config ' , False ) :
2022-10-18 09:51:57 +00:00
apply_field ( x , ' value ' , lambda val : val in x . choices , getattr ( x , ' init_field ' , None ) )
apply_field ( x , ' visible ' )
2022-10-15 19:47:03 +00:00
2022-09-04 10:52:01 +00:00
visit ( txt2img_interface , loadsave , " txt2img " )
visit ( img2img_interface , loadsave , " img2img " )
2022-09-11 08:31:16 +00:00
visit ( extras_interface , loadsave , " extras " )
2022-10-17 16:56:23 +00:00
visit ( modelmerger_interface , loadsave , " modelmerger " )
2022-09-04 10:52:01 +00: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 09:08:45 +00:00
return demo
2022-10-14 17:04:47 +00:00
def load_javascript ( raw_response ) :
with open ( os . path . join ( script_path , " script.js " ) , " r " , encoding = " utf8 " ) as jsfile :
javascript = f ' <script> { jsfile . read ( ) } </script> '
2022-09-18 05:37:03 +00:00
2022-10-14 17:04:47 +00:00
jsdir = os . path . join ( script_path , " javascript " )
for filename in sorted ( os . listdir ( jsdir ) ) :
with open ( os . path . join ( jsdir , filename ) , " r " , encoding = " utf8 " ) as jsfile :
javascript + = f " \n <!-- { filename } --><script> { jsfile . read ( ) } </script> "
2022-09-03 09:08:45 +00:00
2022-10-19 06:43:49 +00:00
if cmd_opts . theme is not None :
javascript + = f " \n <script>set_theme( ' { cmd_opts . theme } ' );</script> \n "
2022-09-03 09:08:45 +00:00
2022-10-19 06:43:49 +00:00
javascript + = f " \n <script> { localization . localization_js ( shared . opts . localization ) } </script> "
2022-09-03 09:08:45 +00:00
2022-10-02 18:26:06 +00:00
def template_response ( * args , * * kwargs ) :
2022-10-14 17:04:47 +00:00
res = raw_response ( * args , * * kwargs )
res . body = res . body . replace (
b ' </head> ' , f ' { javascript } </head> ' . encode ( " utf8 " ) )
2022-10-02 18:26:06 +00:00
res . init_headers ( )
return res
gradio . routes . templates . TemplateResponse = template_response
2022-10-12 16:19:34 +00:00
2022-10-14 17:04:47 +00:00
reload_javascript = partial ( load_javascript ,
gradio . routes . templates . TemplateResponse )
reload_javascript ( )