Batch File upload/ Folder upload. Bulk Enhance

-Immediately enhance each image generated
-Added Bulk Enhance
-Added 2 smaller resolutions: 512x512 and 704x704 for faster image generation
-Added default enhance prompts for pre-selections  'face', 'eye', 'mouth', 'hair', 'hand', 'body'
-Added more error handling
This commit is contained in:
ChrisColeTech 2024-08-17 20:08:43 -04:00
parent 8da1d3ff68
commit f1e9a5c426
6 changed files with 1630 additions and 687 deletions

1
.gitignore vendored
View File

@ -53,3 +53,4 @@ user_path_config-deprecated.txt
/.coverage*
/auth.json
.DS_Store
/.venv

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,155 @@
import gradio as gr
import random
import os
import json
import time
import shared
import modules.config
import fooocus_version
import modules.html
import modules.async_worker as worker
import modules.constants as constants
import modules.flags as flags
import modules.gradio_hijack as grh
import modules.style_sorter as style_sorter
import modules.meta_parser
import args_manager
import copy
import launch
from extras.inpaint_mask import SAMOptions
from modules.sdxl_styles import legal_style_names
from modules.private_logger import get_current_html_path
from modules.ui_gradio_extensions import reload_javascript
from modules.auth import auth_enabled, check_auth
from modules.util import is_json
from tkinter import Tk, filedialog
def process_directories(directory_paths):
if not directory_paths:
return "No directories selected."
results = []
for directory in directory_paths:
# List files in the directory
files = os.listdir(directory)
results.append(f"Contents of {directory}:\n" + "\n".join(files))
return "\n\n".join(results)
def update_visibility(x):
# Add more updates for other components
return [gr.update(visible=x), gr.update(visible=x)]
def list_to_string(filenames):
# Join the filenames list into a comma-separated string
file_list = ', '.join(filenames)
return file_list
def on_browse(data_type):
root = Tk()
root.attributes("-topmost", True)
root.withdraw()
if data_type == "Files":
filenames = filedialog.askopenfilenames()
if len(filenames) > 0:
root.destroy()
file_list = list_to_string(filenames)
return file_list
else:
filename = "Files not seleceted"
root.destroy()
return None
elif data_type == "Folder":
filename = filedialog.askdirectory()
if filename:
if os.path.isdir(filename):
root.destroy()
return str(filename)
else:
root.destroy()
return str(filename)
else:
filename = "Folder not seleceted"
root.destroy()
return None
def on_file_change(files, data_type):
if files and data_type == "Files":
return gr.update(visible=True), gr.update(), gr.update(value=True)
# If no files are selected, hide file explorer and clear input_path
if not files and data_type == "Files":
return gr.update(visible=False), gr.update(value=""), gr.update(value=False)
if data_type == "Folder":
return gr.update(visible=False), gr.update(), gr.update(value=True)
return gr.update(visible=False), gr.update(), gr.update(value=False)
def on_input_change(input_path, file_explorer):
if os.path.isdir(input_path):
# Return an empty list if input_path is a directory or empty
return None, gr.update(visible=True), gr.update(value=True)
if not input_path:
# Return an empty list if input_path is a directory or empty
return None, gr.update(visible=False), gr.update(value=False)
# Initialize a dictionary to track unique file names and their paths
unique_file_paths = {}
# Process the input_path string
if input_path:
# Clean up the input path string and split it into a list of file paths
file_paths_list = input_path.strip("()").replace("'", "").split(", ")
# Extract file names and ensure uniqueness
for path in file_paths_list:
file_name = os.path.basename(path)
unique_file_paths[file_name] = path
# Process file_explorer items if provided
if file_explorer:
# Extract 'orig_name' from each file_explorer object and ensure uniqueness
for item in file_explorer:
file_name = os.path.basename(item.orig_name)
# Store the path, replacing any existing path with the same file name
unique_file_paths[file_name] = item.orig_name
# Convert the dictionary values back to a list of unique file paths
if len(unique_file_paths.values()) > 0:
return list(unique_file_paths.values()), gr.update(visible=False), gr.update(value=True)
else:
return None, gr.update(visible=False), gr.update(value=False)
def on_click_clear():
return None, None, gr.update(visible=False), gr.update(visible=False)
# Function to set prompts based on the selected type
def update_prompts(selected_type):
# Ensure selected_type is a valid key and exists in the dictionary
if selected_type in modules.config.default_enhance_prompts:
positive_prompt = modules.config.default_enhance_prompts[selected_type]['positive']
negative_prompt = modules.config.default_enhance_prompts[selected_type]['negative']
return positive_prompt, negative_prompt
else:
# Returning default or empty values
return "Default positive prompt", "Default negative prompt"
def on_selection_change(selected_type):
# Get prompts based on selected_type
positive_prompt, negative_prompt = update_prompts(selected_type[0])
# Return the prompts
return positive_prompt, negative_prompt

View File

@ -7,7 +7,6 @@ import args_manager
import tempfile
import modules.flags
import modules.sdxl_styles
from modules.model_loader import load_file_from_url
from modules.extra_utils import makedirs_with_log, get_files_from_folder, try_eval_env_var
from modules.flags import OutputFormat, Performance, MetadataScheme
@ -21,9 +20,11 @@ def get_config_path(key, default_value):
else:
return os.path.abspath(default_value)
wildcards_max_bfs_depth = 64
config_path = get_config_path('config_path', "./config.txt")
config_example_path = get_config_path('config_example_path', "config_modification_tutorial.txt")
config_example_path = get_config_path(
'config_example_path', "config_modification_tutorial.txt")
config_dict = {}
always_save_keys = []
visited_keys = []
@ -41,9 +42,11 @@ try:
config_dict.update(json.load(json_file))
always_save_keys = list(config_dict.keys())
except Exception as e:
print(f'Failed to load config file "{config_path}" . The reason is: {str(e)}')
print(
f'Failed to load config file "{config_path}" . The reason is: {str(e)}')
print('Please make sure that:')
print(f'1. The file "{config_path}" is a valid text file, and you have access to read it.')
print(
f'1. The file "{config_path}" is a valid text file, and you have access to read it.')
print('2. Use "\\\\" instead of "\\" when describing paths.')
print('3. There is no "," before the last "}".')
print('4. All key/value formats are correct.')
@ -56,7 +59,8 @@ def try_load_deprecated_user_path_config():
return
try:
deprecated_config_dict = json.load(open('user_path_config.txt', "r", encoding="utf-8"))
deprecated_config_dict = json.load(
open('user_path_config.txt', "r", encoding="utf-8"))
def replace_config(old_key, new_key):
if old_key in deprecated_config_dict:
@ -75,7 +79,8 @@ def try_load_deprecated_user_path_config():
replace_config('temp_outputs_path', 'path_outputs')
if deprecated_config_dict.get("default_model", None) == 'juggernautXL_version6Rundiffusion.safetensors':
os.replace('user_path_config.txt', 'user_path_config-deprecated.txt')
os.replace('user_path_config.txt',
'user_path_config-deprecated.txt')
print('Config updated successfully in silence. '
'A backup of previous config is written to "user_path_config-deprecated.txt".')
return
@ -86,7 +91,8 @@ def try_load_deprecated_user_path_config():
print('Loading using deprecated old models and deprecated old configs.')
return
else:
os.replace('user_path_config.txt', 'user_path_config-deprecated.txt')
os.replace('user_path_config.txt',
'user_path_config-deprecated.txt')
print('Config updated successfully by user. '
'A backup of previous config is written to "user_path_config-deprecated.txt".')
return
@ -98,6 +104,7 @@ def try_load_deprecated_user_path_config():
try_load_deprecated_user_path_config()
def get_presets():
preset_folder = 'presets'
presets = ['initial']
@ -107,10 +114,12 @@ def get_presets():
return presets + [f[:f.index(".json")] for f in os.listdir(preset_folder) if f.endswith('.json')]
def update_presets():
global available_presets
available_presets = get_presets()
def try_get_preset_content(preset):
if isinstance(preset, str):
preset_path = os.path.abspath(f'./presets/{preset}.json')
@ -127,18 +136,22 @@ def try_get_preset_content(preset):
print(e)
return {}
available_presets = get_presets()
preset = args_manager.args.preset
config_dict.update(try_get_preset_content(preset))
def get_path_output() -> str:
"""
Checking output path argument and overriding default path.
"""
global config_dict
path_output = get_dir_or_set_default('path_outputs', '../outputs/', make_directory=True)
path_output = get_dir_or_set_default(
'path_outputs', '../outputs/', make_directory=True)
if args_manager.args.output_path:
print(f'Overriding config value path_outputs with {args_manager.args.output_path}')
print(
f'Overriding config value path_outputs with {args_manager.args.output_path}')
config_dict['path_outputs'] = path_output = args_manager.args.output_path
return path_output
@ -172,15 +185,18 @@ def get_dir_or_set_default(key, default_value, as_array=False, make_directory=Fa
return v
if v is not None:
print(f'Failed to load config key: {json.dumps({key:v})} is invalid or does not exist; will use {json.dumps({key:default_value})} instead.')
print(
f'Failed to load config key: {json.dumps({key:v})} is invalid or does not exist; will use {json.dumps({key:default_value})} instead.')
if isinstance(default_value, list):
dp = []
for path in default_value:
abs_path = os.path.abspath(os.path.join(os.path.dirname(__file__), path))
abs_path = os.path.abspath(
os.path.join(os.path.dirname(__file__), path))
dp.append(abs_path)
os.makedirs(abs_path, exist_ok=True)
else:
dp = os.path.abspath(os.path.join(os.path.dirname(__file__), default_value))
dp = os.path.abspath(os.path.join(
os.path.dirname(__file__), default_value))
os.makedirs(dp, exist_ok=True)
if as_array:
dp = [dp]
@ -188,18 +204,26 @@ def get_dir_or_set_default(key, default_value, as_array=False, make_directory=Fa
return dp
paths_checkpoints = get_dir_or_set_default('path_checkpoints', ['../models/checkpoints/'], True)
paths_checkpoints = get_dir_or_set_default(
'path_checkpoints', ['../models/checkpoints/'], True)
paths_loras = get_dir_or_set_default('path_loras', ['../models/loras/'], True)
path_embeddings = get_dir_or_set_default('path_embeddings', '../models/embeddings/')
path_vae_approx = get_dir_or_set_default('path_vae_approx', '../models/vae_approx/')
path_embeddings = get_dir_or_set_default(
'path_embeddings', '../models/embeddings/')
path_vae_approx = get_dir_or_set_default(
'path_vae_approx', '../models/vae_approx/')
path_vae = get_dir_or_set_default('path_vae', '../models/vae/')
path_upscale_models = get_dir_or_set_default('path_upscale_models', '../models/upscale_models/')
path_upscale_models = get_dir_or_set_default(
'path_upscale_models', '../models/upscale_models/')
path_inpaint = get_dir_or_set_default('path_inpaint', '../models/inpaint/')
path_controlnet = get_dir_or_set_default('path_controlnet', '../models/controlnet/')
path_clip_vision = get_dir_or_set_default('path_clip_vision', '../models/clip_vision/')
path_fooocus_expansion = get_dir_or_set_default('path_fooocus_expansion', '../models/prompt_expansion/fooocus_expansion')
path_controlnet = get_dir_or_set_default(
'path_controlnet', '../models/controlnet/')
path_clip_vision = get_dir_or_set_default(
'path_clip_vision', '../models/clip_vision/')
path_fooocus_expansion = get_dir_or_set_default(
'path_fooocus_expansion', '../models/prompt_expansion/fooocus_expansion')
path_wildcards = get_dir_or_set_default('path_wildcards', '../wildcards/')
path_safety_checker = get_dir_or_set_default('path_safety_checker', '../models/safety_checker/')
path_safety_checker = get_dir_or_set_default(
'path_safety_checker', '../models/safety_checker/')
path_sam = get_dir_or_set_default('path_sam', '../models/sam/')
path_outputs = get_path_output()
@ -228,7 +252,8 @@ def get_config_item_or_set_default(key, default_value, validator, disable_empty_
return v
else:
if v is not None:
print(f'Failed to load config key: {json.dumps({key:v})} is invalid; will use {json.dumps({key:default_value})} instead.')
print(
f'Failed to load config key: {json.dumps({key:v})} is invalid; will use {json.dumps({key:default_value})} instead.')
config_dict[key] = default_value
return default_value
@ -274,7 +299,8 @@ default_base_model_name = default_model = get_config_item_or_set_default(
previous_default_models = get_config_item_or_set_default(
key='previous_default_models',
default_value=[],
validator=lambda x: isinstance(x, list) and all(isinstance(k, str) for k in x),
validator=lambda x: isinstance(x, list) and all(
isinstance(k, str) for k in x),
expected_type=list
)
default_refiner_model_name = default_refiner = get_config_item_or_set_default(
@ -331,15 +357,18 @@ default_loras = get_config_item_or_set_default(
]
],
validator=lambda x: isinstance(x, list) and all(
len(y) == 3 and isinstance(y[0], bool) and isinstance(y[1], str) and isinstance(y[2], numbers.Number)
len(y) == 3 and isinstance(y[0], bool) and isinstance(
y[1], str) and isinstance(y[2], numbers.Number)
or len(y) == 2 and isinstance(y[0], str) and isinstance(y[1], numbers.Number)
for y in x),
expected_type=list
)
default_loras = [(y[0], y[1], y[2]) if len(y) == 3 else (True, y[0], y[1]) for y in default_loras]
default_loras = [(y[0], y[1], y[2]) if len(y) == 3 else (
True, y[0], y[1]) for y in default_loras]
default_max_lora_number = get_config_item_or_set_default(
key='default_max_lora_number',
default_value=len(default_loras) if isinstance(default_loras, list) and len(default_loras) > 0 else 5,
default_value=len(default_loras) if isinstance(
default_loras, list) and len(default_loras) > 0 else 5,
validator=lambda x: isinstance(x, int) and x >= 1,
expected_type=int
)
@ -380,7 +409,8 @@ default_styles = get_config_item_or_set_default(
"Fooocus Enhance",
"Fooocus Sharp"
],
validator=lambda x: isinstance(x, list) and all(y in modules.sdxl_styles.legal_style_names for y in x),
validator=lambda x: isinstance(x, list) and all(
y in modules.sdxl_styles.legal_style_names for y in x),
expected_type=list
)
default_prompt_negative = get_config_item_or_set_default(
@ -448,37 +478,43 @@ default_output_format = get_config_item_or_set_default(
default_image_number = get_config_item_or_set_default(
key='default_image_number',
default_value=2,
validator=lambda x: isinstance(x, int) and 1 <= x <= default_max_image_number,
validator=lambda x: isinstance(
x, int) and 1 <= x <= default_max_image_number,
expected_type=int
)
checkpoint_downloads = get_config_item_or_set_default(
key='checkpoint_downloads',
default_value={},
validator=lambda x: isinstance(x, dict) and all(isinstance(k, str) and isinstance(v, str) for k, v in x.items()),
validator=lambda x: isinstance(x, dict) and all(
isinstance(k, str) and isinstance(v, str) for k, v in x.items()),
expected_type=dict
)
lora_downloads = get_config_item_or_set_default(
key='lora_downloads',
default_value={},
validator=lambda x: isinstance(x, dict) and all(isinstance(k, str) and isinstance(v, str) for k, v in x.items()),
validator=lambda x: isinstance(x, dict) and all(
isinstance(k, str) and isinstance(v, str) for k, v in x.items()),
expected_type=dict
)
embeddings_downloads = get_config_item_or_set_default(
key='embeddings_downloads',
default_value={},
validator=lambda x: isinstance(x, dict) and all(isinstance(k, str) and isinstance(v, str) for k, v in x.items()),
validator=lambda x: isinstance(x, dict) and all(
isinstance(k, str) and isinstance(v, str) for k, v in x.items()),
expected_type=dict
)
vae_downloads = get_config_item_or_set_default(
key='vae_downloads',
default_value={},
validator=lambda x: isinstance(x, dict) and all(isinstance(k, str) and isinstance(v, str) for k, v in x.items()),
validator=lambda x: isinstance(x, dict) and all(
isinstance(k, str) and isinstance(v, str) for k, v in x.items()),
expected_type=dict
)
available_aspect_ratios = get_config_item_or_set_default(
key='available_aspect_ratios',
default_value=modules.flags.sdxl_aspect_ratios,
validator=lambda x: isinstance(x, list) and all('*' in v for v in x) and len(x) > 1,
validator=lambda x: isinstance(x, list) and all(
'*' in v for v in x) and len(x) > 1,
expected_type=list
)
default_aspect_ratio = get_config_item_or_set_default(
@ -521,7 +557,8 @@ for image_count in range(default_controlnet_image_count):
default_ip_images[image_count] = get_config_item_or_set_default(
key=f'default_ip_image_{image_count}',
default_value='None',
validator=lambda x: x == 'None' or isinstance(x, str) and os.path.exists(x),
validator=lambda x: x == 'None' or isinstance(
x, str) and os.path.exists(x),
expected_type=str
)
@ -571,7 +608,8 @@ default_cfg_tsnr = get_config_item_or_set_default(
default_clip_skip = get_config_item_or_set_default(
key='default_clip_skip',
default_value=2,
validator=lambda x: isinstance(x, int) and 1 <= x <= modules.flags.clip_skip_max,
validator=lambda x: isinstance(
x, int) and 1 <= x <= modules.flags.clip_skip_max,
expected_type=int
)
default_overwrite_step = get_config_item_or_set_default(
@ -596,7 +634,8 @@ example_inpaint_prompts = get_config_item_or_set_default(
default_value=[
'highly detailed face', 'detailed girl face', 'detailed man face', 'detailed hand', 'beautiful eyes'
],
validator=lambda x: isinstance(x, list) and all(isinstance(v, str) for v in x),
validator=lambda x: isinstance(x, list) and all(
isinstance(v, str) for v in x),
expected_type=list
)
example_enhance_detection_prompts = get_config_item_or_set_default(
@ -604,9 +643,38 @@ example_enhance_detection_prompts = get_config_item_or_set_default(
default_value=[
'face', 'eye', 'mouth', 'hair', 'hand', 'body'
],
validator=lambda x: isinstance(x, list) and all(isinstance(v, str) for v in x),
validator=lambda x: isinstance(x, list) and all(
isinstance(v, str) for v in x),
expected_type=list
)
default_enhance_prompts = {
'face': {
'positive': "Enhance the face to ensure clear and detailed features. The face should have a well-defined structure with smooth skin, natural contours, and a balanced complexion. Make sure the expression is natural and engaging.",
'negative': "Avoid any blurriness or distortions in the face. Do not include uneven skin tones, unnatural facial expressions, or any missing facial features. Ensure there are no artifacts or unnatural smoothing that might distort the face's natural appearance."
},
'eye': {
'positive': "Enhance the eyes to be clear, sharp, and vividly detailed. The eyes should have natural reflections and a realistic appearance. Ensure the irises and pupils are distinct, and there are no shadows or blurs affecting the eyes.",
'negative': "Exclude any blurring, distortions, or unnatural reflections in the eyes. Avoid asymmetrical or misaligned eyes, and ensure there are no unnatural colors or artifacts that could detract from a realistic appearance."
},
'mouth': {
'positive': "Enhance the mouth to appear natural and symmetrical. The lips should be smooth and well-defined, with no abnormalities. Ensure the mouth reflects a realistic expression and that teeth are visible only if naturally exposed.",
'negative': "Avoid any distortions, asymmetry, or unnatural shapes in the mouth. Do not include missing or extra teeth, and ensure there are no anomalies or artifacts affecting the mouth's appearance."
},
'hair': {
'positive': "Enhance the hair to look full, natural, and well-styled. The texture should be realistic, with clear individual strands or locks and natural shine. Ensure the color and style match the intended look without any unnatural effects.",
'negative': "Exclude any unnatural textures, blurs, or artifacts in the hair. Avoid colors that look artificial or inconsistent, and ensure there are no missing or irregular sections of hair that could disrupt the natural appearance."
},
'hand': {
'positive': "Enhance the hands to ensure all fingers are clearly visible and well-defined. The hands should have realistic textures and proportions, with no missing or distorted fingers. The overall appearance should be natural and proportional.",
'negative': "Avoid any distortions or missing fingers in the hands. Do not include unnatural shapes or proportions, and ensure there are no anomalies or artifacts that affect the realistic appearance of the hands."
},
'body': {
'positive': "Enhance the body to ensure a complete and natural appearance with all limbs properly defined. The body should reflect realistic proportions and posture, with no missing or distorted body parts. Ensure the overall shape and anatomy are natural and well-balanced.",
'negative': "Exclude any missing limbs, distortions, or unrealistic body shapes. Avoid anomalies in body posture or proportions, and ensure there are no artifacts or inconsistencies that could affect the natural appearance of the body."
}
}
default_enhance_tabs = get_config_item_or_set_default(
key='default_enhance_tabs',
default_value=3,
@ -658,7 +726,8 @@ default_save_metadata_to_images = get_config_item_or_set_default(
default_metadata_scheme = get_config_item_or_set_default(
key='default_metadata_scheme',
default_value=MetadataScheme.FOOOCUS.value,
validator=lambda x: x in [y[1] for y in modules.flags.metadata_scheme if y[1] == x],
validator=lambda x: x in [y[1]
for y in modules.flags.metadata_scheme if y[1] == x],
expected_type=str
)
metadata_created_by = get_config_item_or_set_default(
@ -669,7 +738,8 @@ metadata_created_by = get_config_item_or_set_default(
)
example_inpaint_prompts = [[x] for x in example_inpaint_prompts]
example_enhance_detection_prompts = [[x] for x in example_enhance_detection_prompts]
example_enhance_detection_prompts = [[x]
for x in example_enhance_detection_prompts]
default_invert_mask_checkbox = get_config_item_or_set_default(
key='default_invert_mask_checkbox',
@ -719,7 +789,9 @@ default_describe_content_type = get_config_item_or_set_default(
expected_type=list
)
config_dict["default_loras"] = default_loras = default_loras[:default_max_lora_number] + [[True, 'None', 1.0] for _ in range(default_max_lora_number - len(default_loras))]
config_dict["default_loras"] = default_loras = default_loras[:default_max_lora_number] + \
[[True, 'None', 1.0]
for _ in range(default_max_lora_number - len(default_loras))]
# mapping config to meta parameter
possible_preset_keys = {
@ -759,7 +831,8 @@ REWRITE_PRESET = False
if REWRITE_PRESET and isinstance(args_manager.args.preset, str):
save_path = 'presets/' + args_manager.args.preset + '.json'
with open(save_path, "w", encoding="utf-8") as json_file:
json.dump({k: config_dict[k] for k in possible_preset_keys}, json_file, indent=4)
json.dump({k: config_dict[k]
for k in possible_preset_keys}, json_file, indent=4)
print(f'Preset saved to {save_path}. Exiting ...')
exit(0)
@ -772,13 +845,15 @@ def add_ratio(x):
default_aspect_ratio = add_ratio(default_aspect_ratio)
available_aspect_ratios_labels = [add_ratio(x) for x in available_aspect_ratios]
available_aspect_ratios_labels = [
add_ratio(x) for x in available_aspect_ratios]
# Only write config in the first launch.
if not os.path.exists(config_path):
with open(config_path, "w", encoding="utf-8") as json_file:
json.dump({k: config_dict[k] for k in always_save_keys}, json_file, indent=4)
json.dump({k: config_dict[k]
for k in always_save_keys}, json_file, indent=4)
# Always write tutorials.
@ -799,7 +874,8 @@ wildcard_filenames = []
def get_model_filenames(folder_paths, extensions=None, name_filter=None):
if extensions is None:
extensions = ['.pth', '.ckpt', '.bin', '.safetensors', '.fooocus.patch']
extensions = ['.pth', '.ckpt', '.bin',
'.safetensors', '.fooocus.patch']
files = []
if not isinstance(folder_paths, list):
@ -913,14 +989,16 @@ def downloading_ip_adapters(v):
model_dir=path_clip_vision,
file_name='clip_vision_vit_h.safetensors'
)
results += [os.path.join(path_clip_vision, 'clip_vision_vit_h.safetensors')]
results += [os.path.join(path_clip_vision,
'clip_vision_vit_h.safetensors')]
load_file_from_url(
url='https://huggingface.co/lllyasviel/misc/resolve/main/fooocus_ip_negative.safetensors',
model_dir=path_controlnet,
file_name='fooocus_ip_negative.safetensors'
)
results += [os.path.join(path_controlnet, 'fooocus_ip_negative.safetensors')]
results += [os.path.join(path_controlnet,
'fooocus_ip_negative.safetensors')]
if v == 'ip':
load_file_from_url(
@ -928,7 +1006,8 @@ def downloading_ip_adapters(v):
model_dir=path_controlnet,
file_name='ip-adapter-plus_sdxl_vit-h.bin'
)
results += [os.path.join(path_controlnet, 'ip-adapter-plus_sdxl_vit-h.bin')]
results += [os.path.join(path_controlnet,
'ip-adapter-plus_sdxl_vit-h.bin')]
if v == 'face':
load_file_from_url(
@ -936,7 +1015,8 @@ def downloading_ip_adapters(v):
model_dir=path_controlnet,
file_name='ip-adapter-plus-face_sdxl_vit-h.bin'
)
results += [os.path.join(path_controlnet, 'ip-adapter-plus-face_sdxl_vit-h.bin')]
results += [os.path.join(path_controlnet,
'ip-adapter-plus-face_sdxl_vit-h.bin')]
return results
@ -949,6 +1029,7 @@ def downloading_upscale_model():
)
return os.path.join(path_upscale_models, 'fooocus_upscaler_s409985e5.bin')
def downloading_safety_checker_model():
load_file_from_url(
url='https://huggingface.co/mashb1t/misc/resolve/main/stable-diffusion-safety-checker.bin',

View File

@ -8,17 +8,21 @@ upscale_15 = 'Upscale (1.5x)'
upscale_2 = 'Upscale (2x)'
upscale_fast = 'Upscale (Fast 2x)'
uov_list = [disabled, subtle_variation, strong_variation, upscale_15, upscale_2, upscale_fast]
uov_list = [disabled, subtle_variation, strong_variation,
upscale_15, upscale_2, upscale_fast]
enhancement_uov_before = "Before First Enhancement"
enhancement_uov_after = "After Last Enhancement"
enhancement_uov_processing_order = [enhancement_uov_before, enhancement_uov_after]
enhancement_uov_processing_order = [
enhancement_uov_before, enhancement_uov_after]
enhancement_uov_prompt_type_original = 'Original Prompts'
enhancement_uov_prompt_type_last_filled = 'Last Filled Enhancement Prompts'
enhancement_uov_prompt_types = [enhancement_uov_prompt_type_original, enhancement_uov_prompt_type_last_filled]
enhancement_uov_prompt_types = [
enhancement_uov_prompt_type_original, enhancement_uov_prompt_type_last_filled]
CIVITAI_NO_KARRAS = ["euler", "euler_ancestral", "heun", "dpm_fast", "dpm_adaptive", "ddim", "uni_pc"]
CIVITAI_NO_KARRAS = ["euler", "euler_ancestral", "heun",
"dpm_fast", "dpm_adaptive", "ddim", "uni_pc"]
# fooocus: a1111 (Civitai)
KSAMPLER = {
@ -55,7 +59,8 @@ SAMPLERS = KSAMPLER | SAMPLER_EXTRA
KSAMPLER_NAMES = list(KSAMPLER.keys())
SCHEDULER_NAMES = ["normal", "karras", "exponential", "sgm_uniform", "simple", "ddim_uniform", "lcm", "turbo", "align_your_steps", "tcd", "edm_playground_v2.5"]
SCHEDULER_NAMES = ["normal", "karras", "exponential", "sgm_uniform", "simple",
"ddim_uniform", "lcm", "turbo", "align_your_steps", "tcd", "edm_playground_v2.5"]
SAMPLER_NAMES = KSAMPLER_NAMES + list(SAMPLER_EXTRA.keys())
sampler_list = SAMPLER_NAMES
@ -68,7 +73,8 @@ default_vae = 'Default (model)'
refiner_swap_method = 'joint'
default_input_image_tab = 'uov_tab'
input_image_tab_ids = ['uov_tab', 'ip_tab', 'inpaint_tab', 'describe_tab', 'enhance_tab', 'metadata_tab']
input_image_tab_ids = ['uov_tab', 'ip_tab', 'inpaint_tab',
'describe_tab', 'enhance_tab', 'metadata_tab']
cn_ip = "ImagePrompt"
cn_ip_face = "FaceSwap"
@ -84,7 +90,8 @@ default_parameters = {
output_formats = ['png', 'jpeg', 'webp']
inpaint_mask_models = ['u2net', 'u2netp', 'u2net_human_seg', 'u2net_cloth_seg', 'silueta', 'isnet-general-use', 'isnet-anime', 'sam']
inpaint_mask_models = ['u2net', 'u2netp', 'u2net_human_seg',
'u2net_cloth_seg', 'silueta', 'isnet-general-use', 'isnet-anime', 'sam']
inpaint_mask_cloth_category = ['full', 'upper', 'lower']
inpaint_mask_sam_model = ['vit_b', 'vit_l', 'vit_h']
@ -92,14 +99,15 @@ inpaint_engine_versions = ['None', 'v1', 'v2.5', 'v2.6']
inpaint_option_default = 'Inpaint or Outpaint (default)'
inpaint_option_detail = 'Improve Detail (face, hand, eyes, etc.)'
inpaint_option_modify = 'Modify Content (add objects, change background, etc.)'
inpaint_options = [inpaint_option_default, inpaint_option_detail, inpaint_option_modify]
inpaint_options = [inpaint_option_default,
inpaint_option_detail, inpaint_option_modify]
describe_type_photo = 'Photograph'
describe_type_anime = 'Art/Anime'
describe_types = [describe_type_photo, describe_type_anime]
sdxl_aspect_ratios = [
'704*1408', '704*1344', '768*1344', '768*1280', '832*1216', '832*1152',
'512*512', '704*704', '704*1408', '704*1344', '768*1344', '768*1280', '832*1216', '832*1152',
'896*1152', '896*1088', '960*1088', '960*1024', '1024*1024', '1024*960',
'1088*960', '1088*896', '1152*896', '1152*832', '1216*832', '1280*768',
'1344*768', '1344*704', '1408*704', '1472*704', '1536*640', '1600*640',

448
webui.py
View File

@ -23,6 +23,9 @@ from modules.private_logger import get_current_html_path
from modules.ui_gradio_extensions import reload_javascript
from modules.auth import auth_enabled, check_auth
from modules.util import is_json
from tkinter import Tk, filedialog
from modules.bulk_enhance_helpers import *
def get_task(*args):
args = list(args)
@ -30,6 +33,7 @@ def get_task(*args):
return worker.AsyncTask(args=args)
def generate_clicked(task: worker.AsyncTask):
import ldm_patched.modules.model_management as model_management
@ -58,7 +62,8 @@ def generate_clicked(task: worker.AsyncTask):
# help bad internet connection by skipping duplicated preview
if len(task.yields) > 0: # if we have the next item
if task.yields[0][0] == 'preview': # if the next item is also a preview
# if the next item is also a preview
if task.yields[0][0] == 'preview':
# print('Skipped one preview for better internet connection.')
continue
@ -73,8 +78,6 @@ def generate_clicked(task: worker.AsyncTask):
gr.update(visible=True, value=product), \
gr.update(visible=False)
if flag == 'finish':
if not args_manager.args.disable_enhance_output_sorting:
product = sort_enhance_images(product, task)
yield gr.update(visible=False), \
gr.update(visible=False), \
@ -122,7 +125,8 @@ def inpaint_mode_change(mode, inpaint_engine_version):
if mode == modules.flags.inpaint_option_detail:
return [
gr.update(visible=True), gr.update(visible=False, value=[]),
gr.Dataset.update(visible=True, samples=modules.config.example_inpaint_prompts),
gr.Dataset.update(
visible=True, samples=modules.config.example_inpaint_prompts),
False, 'None', 0.5, 0.0
]
@ -132,19 +136,22 @@ def inpaint_mode_change(mode, inpaint_engine_version):
if mode == modules.flags.inpaint_option_modify:
return [
gr.update(visible=True), gr.update(visible=False, value=[]),
gr.Dataset.update(visible=False, samples=modules.config.example_inpaint_prompts),
gr.Dataset.update(
visible=False, samples=modules.config.example_inpaint_prompts),
True, inpaint_engine_version, 1.0, 0.0
]
return [
gr.update(visible=False, value=''), gr.update(visible=True),
gr.Dataset.update(visible=False, samples=modules.config.example_inpaint_prompts),
gr.Dataset.update(
visible=False, samples=modules.config.example_inpaint_prompts),
False, inpaint_engine_version, 1.0, 0.618
]
reload_javascript()
title = f'Fooocus {fooocus_version.version}'
if isinstance(args_manager.args.preset, str):
@ -165,7 +172,8 @@ with shared.gradio_root:
progress_html = gr.HTML(value=modules.html.make_progress_html(32, 'Progress 32%'), visible=False,
elem_id='progress-bar', elem_classes='progress-bar')
gallery = gr.Gallery(label='Gallery', show_label=False, object_fit='contain', visible=True, height=768,
elem_classes=['resizable_area', 'main_view', 'final_gallery', 'image_gallery'],
elem_classes=[
'resizable_area', 'main_view', 'final_gallery', 'image_gallery'],
elem_id='final_gallery')
with gr.Row():
with gr.Column(scale=17):
@ -174,14 +182,20 @@ with shared.gradio_root:
default_prompt = modules.config.default_prompt
if isinstance(default_prompt, str) and default_prompt != '':
shared.gradio_root.load(lambda: default_prompt, outputs=prompt)
shared.gradio_root.load(
lambda: default_prompt, outputs=prompt)
with gr.Column(scale=3, min_width=0):
generate_button = gr.Button(label="Generate", value="Generate", elem_classes='type_row', elem_id='generate_button', visible=True)
reset_button = gr.Button(label="Reconnect", value="Reconnect", elem_classes='type_row', elem_id='reset_button', visible=False)
load_parameter_button = gr.Button(label="Load Parameters", value="Load Parameters", elem_classes='type_row', elem_id='load_parameter_button', visible=False)
skip_button = gr.Button(label="Skip", value="Skip", elem_classes='type_row_half', elem_id='skip_button', visible=False)
stop_button = gr.Button(label="Stop", value="Stop", elem_classes='type_row_half', elem_id='stop_button', visible=False)
generate_button = gr.Button(
label="Generate", value="Generate", elem_classes='type_row', elem_id='generate_button', visible=True)
reset_button = gr.Button(label="Reconnect", value="Reconnect",
elem_classes='type_row', elem_id='reset_button', visible=False)
load_parameter_button = gr.Button(
label="Load Parameters", value="Load Parameters", elem_classes='type_row', elem_id='load_parameter_button', visible=False)
skip_button = gr.Button(
label="Skip", value="Skip", elem_classes='type_row_half', elem_id='skip_button', visible=False)
stop_button = gr.Button(
label="Stop", value="Stop", elem_classes='type_row_half', elem_id='stop_button', visible=False)
def stop_clicked(currentTask):
import ldm_patched.modules.model_management as model_management
@ -197,21 +211,31 @@ with shared.gradio_root:
model_management.interrupt_current_processing()
return currentTask
stop_button.click(stop_clicked, inputs=currentTask, outputs=currentTask, queue=False, show_progress=False, _js='cancelGenerateForever')
skip_button.click(skip_clicked, inputs=currentTask, outputs=currentTask, queue=False, show_progress=False)
stop_button.click(stop_clicked, inputs=currentTask, outputs=currentTask,
queue=False, show_progress=False, _js='cancelGenerateForever')
skip_button.click(skip_clicked, inputs=currentTask,
outputs=currentTask, queue=False, show_progress=False)
with gr.Row(elem_classes='advanced_check_row'):
input_image_checkbox = gr.Checkbox(label='Input Image', value=modules.config.default_image_prompt_checkbox, container=False, elem_classes='min_check')
enhance_checkbox = gr.Checkbox(label='Enhance', value=modules.config.default_enhance_checkbox, container=False, elem_classes='min_check')
advanced_checkbox = gr.Checkbox(label='Advanced', value=modules.config.default_advanced_checkbox, container=False, elem_classes='min_check')
input_image_checkbox = gr.Checkbox(
label='Input Image', value=modules.config.default_image_prompt_checkbox, container=False, elem_classes='min_check')
enhance_checkbox = gr.Checkbox(
label='Enhance', value=modules.config.default_enhance_checkbox, container=False, elem_classes='min_check')
advanced_checkbox = gr.Checkbox(
label='Advanced', value=modules.config.default_advanced_checkbox, container=False, elem_classes='min_check')
# TABS
with gr.Row(visible=modules.config.default_image_prompt_checkbox) as image_input_panel:
with gr.Tabs(selected=modules.config.default_selected_image_input_tab_id):
with gr.Tab(label='Upscale or Variation', id='uov_tab') as uov_tab:
with gr.Row():
with gr.Column():
uov_input_image = grh.Image(label='Image', source='upload', type='numpy', show_label=False)
uov_input_image = grh.Image(
label='Image', source='upload', type='numpy', show_label=False)
with gr.Column():
uov_method = gr.Radio(label='Upscale or Variation:', choices=flags.uov_list, value=modules.config.default_uov_method)
gr.HTML('<a href="https://github.com/lllyasviel/Fooocus/discussions/390" target="_blank">\U0001F4D4 Documentation</a>')
uov_method = gr.Radio(
label='Upscale or Variation:', choices=flags.uov_list, value=modules.config.default_uov_method)
gr.HTML(
'<a href="https://github.com/lllyasviel/Fooocus/discussions/390" target="_blank">\U0001F4D4 Documentation</a>')
with gr.Tab(label='Image Prompt', id='ip_tab') as ip_tab:
with gr.Row():
ip_images = []
@ -223,33 +247,40 @@ with shared.gradio_root:
for image_count in range(modules.config.default_controlnet_image_count):
image_count += 1
with gr.Column():
ip_image = grh.Image(label='Image', source='upload', type='numpy', show_label=False, height=300, value=modules.config.default_ip_images[image_count])
ip_image = grh.Image(label='Image', source='upload', type='numpy', show_label=False,
height=300, value=modules.config.default_ip_images[image_count])
ip_images.append(ip_image)
ip_ctrls.append(ip_image)
with gr.Column(visible=modules.config.default_image_prompt_advanced_checkbox) as ad_col:
with gr.Row():
ip_stop = gr.Slider(label='Stop At', minimum=0.0, maximum=1.0, step=0.001, value=modules.config.default_ip_stop_ats[image_count])
ip_stop = gr.Slider(
label='Stop At', minimum=0.0, maximum=1.0, step=0.001, value=modules.config.default_ip_stop_ats[image_count])
ip_stops.append(ip_stop)
ip_ctrls.append(ip_stop)
ip_weight = gr.Slider(label='Weight', minimum=0.0, maximum=2.0, step=0.001, value=modules.config.default_ip_weights[image_count])
ip_weight = gr.Slider(
label='Weight', minimum=0.0, maximum=2.0, step=0.001, value=modules.config.default_ip_weights[image_count])
ip_weights.append(ip_weight)
ip_ctrls.append(ip_weight)
ip_type = gr.Radio(label='Type', choices=flags.ip_list, value=modules.config.default_ip_types[image_count], container=False)
ip_type = gr.Radio(
label='Type', choices=flags.ip_list, value=modules.config.default_ip_types[image_count], container=False)
ip_types.append(ip_type)
ip_ctrls.append(ip_type)
ip_type.change(lambda x: flags.default_parameters[x], inputs=[ip_type], outputs=[ip_stop, ip_weight], queue=False, show_progress=False)
ip_type.change(lambda x: flags.default_parameters[x], inputs=[ip_type], outputs=[
ip_stop, ip_weight], queue=False, show_progress=False)
ip_ad_cols.append(ad_col)
ip_advanced = gr.Checkbox(label='Advanced', value=modules.config.default_image_prompt_advanced_checkbox, container=False)
ip_advanced = gr.Checkbox(
label='Advanced', value=modules.config.default_image_prompt_advanced_checkbox, container=False)
gr.HTML('* \"Image Prompt\" is powered by Fooocus Image Mixture Engine (v1.0.1). <a href="https://github.com/lllyasviel/Fooocus/discussions/557" target="_blank">\U0001F4D4 Documentation</a>')
def ip_advance_checked(x):
return [gr.update(visible=x)] * len(ip_ad_cols) + \
[flags.default_ip] * len(ip_types) + \
[flags.default_parameters[flags.default_ip][0]] * len(ip_stops) + \
[flags.default_parameters[flags.default_ip][1]] * len(ip_weights)
[flags.default_parameters[flags.default_ip]
[1]] * len(ip_weights)
ip_advanced.change(ip_advance_checked, inputs=ip_advanced,
outputs=ip_ad_cols + ip_types + ip_stops + ip_weights,
@ -258,21 +289,31 @@ with shared.gradio_root:
with gr.Tab(label='Inpaint or Outpaint', id='inpaint_tab') as inpaint_tab:
with gr.Row():
with gr.Column():
inpaint_input_image = grh.Image(label='Image', source='upload', type='numpy', tool='sketch', height=500, brush_color="#FFFFFF", elem_id='inpaint_canvas', show_label=False)
inpaint_advanced_masking_checkbox = gr.Checkbox(label='Enable Advanced Masking Features', value=modules.config.default_inpaint_advanced_masking_checkbox)
inpaint_mode = gr.Dropdown(choices=modules.flags.inpaint_options, value=modules.config.default_inpaint_method, label='Method')
inpaint_additional_prompt = gr.Textbox(placeholder="Describe what you want to inpaint.", elem_id='inpaint_additional_prompt', label='Inpaint Additional Prompt', visible=False)
outpaint_selections = gr.CheckboxGroup(choices=['Left', 'Right', 'Top', 'Bottom'], value=[], label='Outpaint Direction')
inpaint_input_image = grh.Image(label='Image', source='upload', type='numpy', tool='sketch',
height=500, brush_color="#FFFFFF", elem_id='inpaint_canvas', show_label=False)
inpaint_advanced_masking_checkbox = gr.Checkbox(
label='Enable Advanced Masking Features', value=modules.config.default_inpaint_advanced_masking_checkbox)
inpaint_mode = gr.Dropdown(
choices=modules.flags.inpaint_options, value=modules.config.default_inpaint_method, label='Method')
inpaint_additional_prompt = gr.Textbox(
placeholder="Describe what you want to inpaint.", elem_id='inpaint_additional_prompt', label='Inpaint Additional Prompt', visible=False)
outpaint_selections = gr.CheckboxGroup(
choices=['Left', 'Right', 'Top', 'Bottom'], value=[], label='Outpaint Direction')
example_inpaint_prompts = gr.Dataset(samples=modules.config.example_inpaint_prompts,
label='Additional Prompt Quick List',
components=[inpaint_additional_prompt],
components=[
inpaint_additional_prompt],
visible=False)
gr.HTML('* Powered by Fooocus Inpaint Engine <a href="https://github.com/lllyasviel/Fooocus/discussions/414" target="_blank">\U0001F4D4 Documentation</a>')
example_inpaint_prompts.click(lambda x: x[0], inputs=example_inpaint_prompts, outputs=inpaint_additional_prompt, show_progress=False, queue=False)
gr.HTML(
'* Powered by Fooocus Inpaint Engine <a href="https://github.com/lllyasviel/Fooocus/discussions/414" target="_blank">\U0001F4D4 Documentation</a>')
example_inpaint_prompts.click(
lambda x: x[0], inputs=example_inpaint_prompts, outputs=inpaint_additional_prompt, show_progress=False, queue=False)
with gr.Column(visible=modules.config.default_inpaint_advanced_masking_checkbox) as inpaint_mask_generation_col:
inpaint_mask_image = grh.Image(label='Mask Upload', source='upload', type='numpy', tool='sketch', height=500, brush_color="#FFFFFF", mask_opacity=1, elem_id='inpaint_mask_canvas')
invert_mask_checkbox = gr.Checkbox(label='Invert Mask When Generating', value=modules.config.default_invert_mask_checkbox)
inpaint_mask_image = grh.Image(label='Mask Upload', source='upload', type='numpy', tool='sketch',
height=500, brush_color="#FFFFFF", mask_opacity=1, elem_id='inpaint_mask_canvas')
invert_mask_checkbox = gr.Checkbox(
label='Invert Mask When Generating', value=modules.config.default_invert_mask_checkbox)
inpaint_mask_model = gr.Dropdown(label='Mask generation model',
choices=flags.inpaint_mask_models,
value=modules.config.default_inpaint_mask_model)
@ -280,7 +321,8 @@ with shared.gradio_root:
choices=flags.inpaint_mask_cloth_category,
value=modules.config.default_inpaint_mask_cloth_category,
visible=False)
inpaint_mask_dino_prompt_text = gr.Textbox(label='Detection prompt', value='', visible=False, info='Use singular whenever possible', placeholder='Describe what you want to detect.')
inpaint_mask_dino_prompt_text = gr.Textbox(
label='Detection prompt', value='', visible=False, info='Use singular whenever possible', placeholder='Describe what you want to detect.')
example_inpaint_mask_dino_prompt_text = gr.Dataset(
samples=modules.config.example_enhance_detection_prompts,
label='Detection Prompt Quick List',
@ -292,11 +334,16 @@ with shared.gradio_root:
show_progress=False, queue=False)
with gr.Accordion("Advanced options", visible=False, open=False) as inpaint_mask_advanced_options:
inpaint_mask_sam_model = gr.Dropdown(label='SAM model', choices=flags.inpaint_mask_sam_model, value=modules.config.default_inpaint_mask_sam_model)
inpaint_mask_box_threshold = gr.Slider(label="Box Threshold", minimum=0.0, maximum=1.0, value=0.3, step=0.05)
inpaint_mask_text_threshold = gr.Slider(label="Text Threshold", minimum=0.0, maximum=1.0, value=0.25, step=0.05)
inpaint_mask_sam_max_detections = gr.Slider(label="Maximum number of detections", info="Set to 0 to detect all", minimum=0, maximum=10, value=modules.config.default_sam_max_detections, step=1, interactive=True)
generate_mask_button = gr.Button(value='Generate mask from image')
inpaint_mask_sam_model = gr.Dropdown(
label='SAM model', choices=flags.inpaint_mask_sam_model, value=modules.config.default_inpaint_mask_sam_model)
inpaint_mask_box_threshold = gr.Slider(
label="Box Threshold", minimum=0.0, maximum=1.0, value=0.3, step=0.05)
inpaint_mask_text_threshold = gr.Slider(
label="Text Threshold", minimum=0.0, maximum=1.0, value=0.25, step=0.05)
inpaint_mask_sam_max_detections = gr.Slider(
label="Maximum number of detections", info="Set to 0 to detect all", minimum=0, maximum=10, value=modules.config.default_sam_max_detections, step=1, interactive=True)
generate_mask_button = gr.Button(
value='Generate mask from image')
def generate_mask(image, mask_model, cloth_category, dino_prompt_text, sam_model, box_threshold, text_threshold, sam_max_detections, dino_erode_or_dilate, dino_debug):
from extras.inpaint_mask import generate_mask_from_image
@ -316,11 +363,11 @@ with shared.gradio_root:
model_type=sam_model
)
mask, _, _, _ = generate_mask_from_image(image, mask_model, extras, sam_options)
mask, _, _, _ = generate_mask_from_image(
image, mask_model, extras, sam_options)
return mask
inpaint_mask_model.change(lambda x: [gr.update(visible=x == 'u2net_cloth_seg')] +
[gr.update(visible=x == 'sam')] * 2 +
[gr.Dataset.update(visible=x == 'sam',
@ -335,19 +382,25 @@ with shared.gradio_root:
with gr.Tab(label='Describe', id='describe_tab') as describe_tab:
with gr.Row():
with gr.Column():
describe_input_image = grh.Image(label='Image', source='upload', type='numpy', show_label=False)
describe_input_image = grh.Image(
label='Image', source='upload', type='numpy', show_label=False)
with gr.Column():
describe_methods = gr.CheckboxGroup(
label='Content Type',
choices=flags.describe_types,
value=modules.config.default_describe_content_type)
describe_apply_styles = gr.Checkbox(label='Apply Styles', value=modules.config.default_describe_apply_prompts_checkbox)
describe_btn = gr.Button(value='Describe this Image into Prompt')
describe_image_size = gr.Textbox(label='Image Size and Recommended Size', elem_id='describe_image_size', visible=False)
gr.HTML('<a href="https://github.com/lllyasviel/Fooocus/discussions/1363" target="_blank">\U0001F4D4 Documentation</a>')
describe_apply_styles = gr.Checkbox(
label='Apply Styles', value=modules.config.default_describe_apply_prompts_checkbox)
describe_btn = gr.Button(
value='Describe this Image into Prompt')
describe_image_size = gr.Textbox(
label='Image Size and Recommended Size', elem_id='describe_image_size', visible=False)
gr.HTML(
'<a href="https://github.com/lllyasviel/Fooocus/discussions/1363" target="_blank">\U0001F4D4 Documentation</a>')
def trigger_show_image_properties(image):
value = modules.util.get_image_size_info(image, modules.flags.sdxl_aspect_ratios)
value = modules.util.get_image_size_info(
image, modules.flags.sdxl_aspect_ratios)
return gr.update(value=value, visible=True)
describe_input_image.upload(trigger_show_image_properties, inputs=describe_input_image,
@ -356,17 +409,22 @@ with shared.gradio_root:
with gr.Tab(label='Enhance', id='enhance_tab') as enhance_tab:
with gr.Row():
with gr.Column():
enhance_input_image = grh.Image(label='Use with Enhance, skips image generation', source='upload', type='numpy')
gr.HTML('<a href="https://github.com/lllyasviel/Fooocus/discussions/3281" target="_blank">\U0001F4D4 Documentation</a>')
enhance_input_image = grh.Image(
label='Use with Enhance, skips image generation', source='upload', type='numpy')
gr.HTML(
'<a href="https://github.com/lllyasviel/Fooocus/discussions/3281" target="_blank">\U0001F4D4 Documentation</a>')
with gr.Tab(label='Metadata', id='metadata_tab') as metadata_tab:
with gr.Column():
metadata_input_image = grh.Image(label='For images created by Fooocus', source='upload', type='pil')
metadata_input_image = grh.Image(
label='For images created by Fooocus', source='upload', type='pil')
metadata_json = gr.JSON(label='Metadata')
metadata_import_button = gr.Button(value='Apply Metadata')
metadata_import_button = gr.Button(
value='Apply Metadata')
def trigger_metadata_preview(file):
parameters, metadata_scheme = modules.meta_parser.read_info_from_image(file)
parameters, metadata_scheme = modules.meta_parser.read_info_from_image(
file)
results = {}
if parameters is not None:
@ -380,7 +438,59 @@ with shared.gradio_root:
metadata_input_image.upload(trigger_metadata_preview, inputs=metadata_input_image,
outputs=metadata_json, queue=False, show_progress=True)
# BULK ENHANCE #
bulk_enhance_ctrls = []
with gr.Row(visible=modules.config.default_enhance_checkbox) as enhance_input_panel:
with gr.Tabs():
with gr.Tab(label='Bulk Enhance'):
bulk_enhance_enabled = gr.Checkbox(label='Enable', value=False, elem_classes='min_check',
container=False, visible=False)
# Create a FileExplorer component
with gr.Row():
bulk_enhance_data_type = gr.Radio(
choices=["Files", "Folder"], value="Files", label="Select Files or Folder:")
with gr.Row(elem_id="file_row", visible=False) as bulk_enhance_file_row:
bulk_enhance_file_explorer = gr.File(
label="Selected Files",
file_count="multiple", # or "single" for single file selection
root_dir=".", # Specify root directory if needed
show_label=True,
elem_id="file_explorer",
name="file_explorer"
)
with gr.Row(elem_id="folder_row", visible=False) as bulk_enhance_folder_row:
bulk_enhance_input_path = gr.Textbox(
label="Selected Folder", max_lines=1, show_label=True, scale=5, interactive=False)
with gr.Row():
with gr.Column():
pass
with gr.Column():
with gr.Blocks():
with gr.Row():
bulk_enhance_image_browse_btn = gr.Button(
"Browse", elem_id="browse-button", size="sm")
bulk_enhance_clear_button = gr.ClearButton(elem_id="clear-button",
size="sm")
bulk_enhance_clear_button.click(on_click_clear, outputs=[
bulk_enhance_file_explorer, bulk_enhance_input_path, bulk_enhance_file_row, bulk_enhance_folder_row])
with gr.Column():
pass
bulk_enhance_ctrls += [
bulk_enhance_enabled,
bulk_enhance_data_type,
bulk_enhance_file_explorer,
bulk_enhance_input_path
]
with gr.Row(visible=modules.config.default_enhance_checkbox) as enhance_input_panel2:
with gr.Row():
with gr.Tabs():
with gr.Tab(label='Upscale or Variation'):
with gr.Row():
@ -401,7 +511,8 @@ with shared.gradio_root:
inputs=enhance_uov_processing_order,
outputs=enhance_uov_prompt_type,
queue=False, show_progress=False)
gr.HTML('<a href="https://github.com/lllyasviel/Fooocus/discussions/3281" target="_blank">\U0001F4D4 Documentation</a>')
gr.HTML(
'<a href="https://github.com/lllyasviel/Fooocus/discussions/3281" target="_blank">\U0001F4D4 Documentation</a>')
enhance_ctrls = []
enhance_inpaint_mode_ctrls = []
enhance_inpaint_engine_ctrls = []
@ -433,6 +544,13 @@ with shared.gradio_root:
placeholder="Uses original negative prompt instead if empty.",
elem_id='enhance_negative_prompt')
# Bind the callback to the selection change
example_enhance_mask_dino_prompt_text.select(
on_selection_change,
inputs=example_enhance_mask_dino_prompt_text,
outputs=[enhance_prompt,
enhance_negative_prompt]
)
with gr.Accordion("Detection", open=False):
enhance_mask_model = gr.Dropdown(label='Mask generation model',
choices=flags.inpaint_mask_models,
@ -491,9 +609,11 @@ with shared.gradio_root:
info='Positive value will make white area in the mask larger, '
'negative value will make white area smaller. '
'(default is 0, always processed before any mask invert)')
enhance_mask_invert = gr.Checkbox(label='Invert Mask', value=False)
enhance_mask_invert = gr.Checkbox(
label='Invert Mask', value=False)
gr.HTML('<a href="https://github.com/lllyasviel/Fooocus/discussions/3281" target="_blank">\U0001F4D4 Documentation</a>')
gr.HTML(
'<a href="https://github.com/lllyasviel/Fooocus/discussions/3281" target="_blank">\U0001F4D4 Documentation</a>')
enhance_ctrls += [
enhance_enabled,
@ -514,8 +634,10 @@ with shared.gradio_root:
enhance_mask_invert
]
enhance_inpaint_mode_ctrls += [enhance_inpaint_mode]
enhance_inpaint_engine_ctrls += [enhance_inpaint_engine]
enhance_inpaint_mode_ctrls += [
enhance_inpaint_mode]
enhance_inpaint_engine_ctrls += [
enhance_inpaint_engine]
enhance_inpaint_update_ctrls += [[
enhance_inpaint_mode, enhance_inpaint_disable_initial_latent, enhance_inpaint_engine,
@ -541,19 +663,45 @@ with shared.gradio_root:
switch_js = "(x) => {if(x){viewer_to_bottom(100);viewer_to_bottom(500);}else{viewer_to_top();} return x;}"
down_js = "() => {viewer_to_bottom();}"
# EVENT HANDLERS
input_image_checkbox.change(lambda x: gr.update(visible=x), inputs=input_image_checkbox,
outputs=image_input_panel, queue=False, show_progress=False, _js=switch_js)
ip_advanced.change(lambda: None, queue=False, show_progress=False, _js=down_js)
ip_advanced.change(lambda: None, queue=False,
show_progress=False, _js=down_js)
current_tab = gr.Textbox(value='uov', visible=False)
uov_tab.select(lambda: 'uov', outputs=current_tab, queue=False, _js=down_js, show_progress=False)
inpaint_tab.select(lambda: 'inpaint', outputs=current_tab, queue=False, _js=down_js, show_progress=False)
ip_tab.select(lambda: 'ip', outputs=current_tab, queue=False, _js=down_js, show_progress=False)
describe_tab.select(lambda: 'desc', outputs=current_tab, queue=False, _js=down_js, show_progress=False)
enhance_tab.select(lambda: 'enhance', outputs=current_tab, queue=False, _js=down_js, show_progress=False)
metadata_tab.select(lambda: 'metadata', outputs=current_tab, queue=False, _js=down_js, show_progress=False)
enhance_checkbox.change(lambda x: gr.update(visible=x), inputs=enhance_checkbox,
outputs=enhance_input_panel, queue=False, show_progress=False, _js=switch_js)
uov_tab.select(lambda: 'uov', outputs=current_tab,
queue=False, _js=down_js, show_progress=False)
inpaint_tab.select(lambda: 'inpaint', outputs=current_tab,
queue=False, _js=down_js, show_progress=False)
ip_tab.select(lambda: 'ip', outputs=current_tab,
queue=False, _js=down_js, show_progress=False)
describe_tab.select(lambda: 'desc', outputs=current_tab,
queue=False, _js=down_js, show_progress=False)
enhance_tab.select(lambda: 'enhance', outputs=current_tab,
queue=False, _js=down_js, show_progress=False)
metadata_tab.select(lambda: 'metadata', outputs=current_tab,
queue=False, _js=down_js, show_progress=False)
enhance_checkbox.change(fn=update_visibility, inputs=enhance_checkbox,
outputs=[enhance_input_panel, enhance_input_panel2], queue=False, show_progress=False, _js=switch_js)
bulk_enhance_image_browse_btn.click(
on_browse, inputs=bulk_enhance_data_type, outputs=bulk_enhance_input_path, show_progress="hidden")
bulk_enhance_file_explorer.change(
on_file_change,
inputs=[bulk_enhance_file_explorer, bulk_enhance_data_type],
# Note: output both file_row and input_path
outputs=[bulk_enhance_file_row,
bulk_enhance_input_path, bulk_enhance_enabled]
)
bulk_enhance_input_path.change(
on_input_change,
inputs=[bulk_enhance_input_path, bulk_enhance_file_explorer],
# Update file_explorer based on input_path
outputs=[bulk_enhance_file_explorer,
bulk_enhance_folder_row, bulk_enhance_enabled]
)
with gr.Column(scale=1, visible=modules.config.default_advanced_checkbox) as advanced_column:
with gr.Tab(label='Settings'):
@ -575,10 +723,13 @@ with shared.gradio_root:
info='width × height',
elem_classes='aspect_ratios')
aspect_ratios_selection.change(lambda x: None, inputs=aspect_ratios_selection, queue=False, show_progress=False, _js='(x)=>{refresh_aspect_ratios_label(x);}')
shared.gradio_root.load(lambda x: None, inputs=aspect_ratios_selection, queue=False, show_progress=False, _js='(x)=>{refresh_aspect_ratios_label(x);}')
aspect_ratios_selection.change(lambda x: None, inputs=aspect_ratios_selection,
queue=False, show_progress=False, _js='(x)=>{refresh_aspect_ratios_label(x);}')
shared.gradio_root.load(lambda x: None, inputs=aspect_ratios_selection, queue=False,
show_progress=False, _js='(x)=>{refresh_aspect_ratios_label(x);}')
image_number = gr.Slider(label='Image Number', minimum=1, maximum=modules.config.default_max_image_number, step=1, value=modules.config.default_image_number)
image_number = gr.Slider(
label='Image Number', minimum=1, maximum=modules.config.default_max_image_number, step=1, value=modules.config.default_image_number)
output_format = gr.Radio(label='Output Format',
choices=flags.OutputFormat.list(),
@ -589,7 +740,9 @@ with shared.gradio_root:
elem_id='negative_prompt',
value=modules.config.default_prompt_negative)
seed_random = gr.Checkbox(label='Random', value=True)
image_seed = gr.Textbox(label='Seed', value=0, max_lines=1, visible=False) # workaround for https://github.com/gradio-app/gradio/issues/5354
# workaround for https://github.com/gradio-app/gradio/issues/5354
image_seed = gr.Textbox(
label='Seed', value=0, max_lines=1, visible=False)
def random_checked(r):
return gr.update(visible=not r)
@ -616,7 +769,8 @@ with shared.gradio_root:
return gr.update(value=f'<a href="file={get_current_html_path(output_format)}" target="_blank">\U0001F4DA History Log</a>')
history_link = gr.HTML()
shared.gradio_root.load(update_history_link, outputs=history_link, queue=False, show_progress=False)
shared.gradio_root.load(
update_history_link, outputs=history_link, queue=False, show_progress=False)
with gr.Tab(label='Styles', elem_classes=['style_selections_tab']):
style_sorter.try_load_sorted_styles(
@ -628,17 +782,21 @@ with shared.gradio_root:
value="",
label='Search Styles')
style_selections = gr.CheckboxGroup(show_label=False, container=False,
choices=copy.deepcopy(style_sorter.all_styles),
value=copy.deepcopy(modules.config.default_styles),
choices=copy.deepcopy(
style_sorter.all_styles),
value=copy.deepcopy(
modules.config.default_styles),
label='Selected Styles',
elem_classes=['style_selections'])
gradio_receiver_style_selections = gr.Textbox(elem_id='gradio_receiver_style_selections', visible=False)
gradio_receiver_style_selections = gr.Textbox(
elem_id='gradio_receiver_style_selections', visible=False)
shared.gradio_root.load(lambda: gr.update(choices=copy.deepcopy(style_sorter.all_styles)),
outputs=style_selections)
style_search_bar.change(style_sorter.search_styles,
inputs=[style_selections, style_search_bar],
inputs=[style_selections,
style_search_bar],
outputs=style_selections,
queue=False,
show_progress=False).then(
@ -654,8 +812,10 @@ with shared.gradio_root:
with gr.Tab(label='Models'):
with gr.Group():
with gr.Row():
base_model = gr.Dropdown(label='Base Model (SDXL only)', choices=modules.config.model_filenames, value=modules.config.default_base_model_name, show_label=True)
refiner_model = gr.Dropdown(label='Refiner (SDXL or SD 1.5)', choices=['None'] + modules.config.model_filenames, value=modules.config.default_refiner_model_name, show_label=True)
base_model = gr.Dropdown(label='Base Model (SDXL only)', choices=modules.config.model_filenames,
value=modules.config.default_base_model_name, show_label=True)
refiner_model = gr.Dropdown(label='Refiner (SDXL or SD 1.5)', choices=[
'None'] + modules.config.model_filenames, value=modules.config.default_refiner_model_name, show_label=True)
refiner_switch = gr.Slider(label='Refiner Switch At', minimum=0.1, maximum=1.0, step=0.0001,
info='Use 0.4 for SD1.5 realistic models; '
@ -681,10 +841,12 @@ with shared.gradio_root:
lora_weight = gr.Slider(label='Weight', minimum=modules.config.default_loras_min_weight,
maximum=modules.config.default_loras_max_weight, step=0.01, value=weight,
elem_classes='lora_weight', scale=5)
lora_ctrls += [lora_enabled, lora_model, lora_weight]
lora_ctrls += [lora_enabled,
lora_model, lora_weight]
with gr.Row():
refresh_files = gr.Button(label='Refresh', value='\U0001f504 Refresh All Files', variant='secondary', elem_classes='refresh_button')
refresh_files = gr.Button(
label='Refresh', value='\U0001f504 Refresh All Files', variant='secondary', elem_classes='refresh_button')
with gr.Tab(label='Advanced'):
guidance_scale = gr.Slider(label='Guidance Scale', minimum=1.0, maximum=30.0, step=0.01,
value=modules.config.default_cfg_scale,
@ -692,8 +854,10 @@ with shared.gradio_root:
sharpness = gr.Slider(label='Image Sharpness', minimum=0.0, maximum=30.0, step=0.001,
value=modules.config.default_sample_sharpness,
info='Higher value means image and texture are sharper.')
gr.HTML('<a href="https://github.com/lllyasviel/Fooocus/discussions/117" target="_blank">\U0001F4D4 Documentation</a>')
dev_mode = gr.Checkbox(label='Developer Debug Mode', value=modules.config.default_developer_debug_mode_checkbox, container=False)
gr.HTML(
'<a href="https://github.com/lllyasviel/Fooocus/discussions/117" target="_blank">\U0001F4D4 Documentation</a>')
dev_mode = gr.Checkbox(
label='Developer Debug Mode', value=modules.config.default_developer_debug_mode_checkbox, container=False)
with gr.Column(visible=modules.config.default_developer_debug_mode_checkbox) as dev_tools:
with gr.Tab(label='Debug Tools'):
@ -754,13 +918,15 @@ with shared.gradio_root:
interactive=not modules.config.default_black_out_nsfw,
info='Disable preview during generation.')
disable_intermediate_results = gr.Checkbox(label='Disable Intermediate Results',
value=flags.Performance.has_restricted_features(modules.config.default_performance),
value=flags.Performance.has_restricted_features(
modules.config.default_performance),
info='Disable intermediate results during generation, only show final gallery.')
disable_seed_increment = gr.Checkbox(label='Disable seed increment',
info='Disable automatic seed increment when image number is > 1.',
value=False)
read_wildcards_in_order = gr.Checkbox(label="Read wildcards in order", value=False)
read_wildcards_in_order = gr.Checkbox(
label="Read wildcards in order", value=False)
black_out_nsfw = gr.Checkbox(label='Black Out NSFW', value=modules.config.default_black_out_nsfw,
interactive=not modules.config.default_black_out_nsfw,
@ -806,12 +972,14 @@ with shared.gradio_root:
step=1, value=128)
with gr.Tab(label='Inpaint'):
debugging_inpaint_preprocessor = gr.Checkbox(label='Debug Inpaint Preprocessing', value=False)
debugging_inpaint_preprocessor = gr.Checkbox(
label='Debug Inpaint Preprocessing', value=False)
debugging_enhance_masks_checkbox = gr.Checkbox(label='Debug Enhance Masks', value=False,
info='Show enhance masks in preview and final results')
debugging_dino = gr.Checkbox(label='Debug GroundingDINO', value=False,
info='Use GroundingDINO boxes instead of more detailed SAM masks')
inpaint_disable_initial_latent = gr.Checkbox(label='Disable initial latent in inpaint', value=False)
inpaint_disable_initial_latent = gr.Checkbox(
label='Disable initial latent in inpaint', value=False)
inpaint_engine = gr.Dropdown(label='Inpaint Engine',
value=modules.config.default_inpaint_engine_version,
choices=flags.inpaint_engine_versions,
@ -839,7 +1007,8 @@ with shared.gradio_root:
'negative value will make white area smaller. '
'(default is 0, processed before SAM)')
inpaint_mask_color = gr.ColorPicker(label='Inpaint brush color', value='#FFFFFF', elem_id='inpaint_brush_color')
inpaint_mask_color = gr.ColorPicker(
label='Inpaint brush color', value='#FFFFFF', elem_id='inpaint_brush_color')
inpaint_ctrls = [debugging_inpaint_preprocessor, inpaint_disable_initial_latent, inpaint_engine,
inpaint_strength, inpaint_respective_field,
@ -847,7 +1016,8 @@ with shared.gradio_root:
inpaint_advanced_masking_checkbox.change(lambda x: [gr.update(visible=x)] * 2,
inputs=inpaint_advanced_masking_checkbox,
outputs=[inpaint_mask_image, inpaint_mask_generation_col],
outputs=[
inpaint_mask_image, inpaint_mask_generation_col],
queue=False, show_progress=False)
inpaint_mask_color.change(lambda x: gr.update(brush_color=x), inputs=inpaint_mask_color,
@ -855,12 +1025,18 @@ with shared.gradio_root:
queue=False, show_progress=False)
with gr.Tab(label='FreeU'):
freeu_enabled = gr.Checkbox(label='Enabled', value=False)
freeu_b1 = gr.Slider(label='B1', minimum=0, maximum=2, step=0.01, value=1.01)
freeu_b2 = gr.Slider(label='B2', minimum=0, maximum=2, step=0.01, value=1.02)
freeu_s1 = gr.Slider(label='S1', minimum=0, maximum=4, step=0.01, value=0.99)
freeu_s2 = gr.Slider(label='S2', minimum=0, maximum=4, step=0.01, value=0.95)
freeu_ctrls = [freeu_enabled, freeu_b1, freeu_b2, freeu_s1, freeu_s2]
freeu_enabled = gr.Checkbox(
label='Enabled', value=False)
freeu_b1 = gr.Slider(
label='B1', minimum=0, maximum=2, step=0.01, value=1.01)
freeu_b2 = gr.Slider(
label='B2', minimum=0, maximum=2, step=0.01, value=1.02)
freeu_s1 = gr.Slider(
label='S1', minimum=0, maximum=4, step=0.01, value=0.99)
freeu_s2 = gr.Slider(
label='S2', minimum=0, maximum=4, step=0.01, value=0.95)
freeu_ctrls = [freeu_enabled, freeu_b1,
freeu_b2, freeu_s1, freeu_s2]
def dev_mode_checked(r):
return gr.update(visible=r)
@ -870,9 +1046,12 @@ with shared.gradio_root:
def refresh_files_clicked():
modules.config.update_files()
results = [gr.update(choices=modules.config.model_filenames)]
results += [gr.update(choices=['None'] + modules.config.model_filenames)]
results += [gr.update(choices=[flags.default_vae] + modules.config.vae_filenames)]
results = [
gr.update(choices=modules.config.model_filenames)]
results += [gr.update(choices=['None'] +
modules.config.model_filenames)]
results += [gr.update(choices=[flags.default_vae] +
modules.config.vae_filenames)]
if not args_manager.args.disable_preset_selection:
results += [gr.update(choices=modules.config.available_presets)]
for i in range(modules.config.default_max_lora_number):
@ -899,13 +1078,18 @@ with shared.gradio_root:
if not args_manager.args.disable_preset_selection:
def preset_selection_change(preset, is_generating, inpaint_mode):
preset_content = modules.config.try_get_preset_content(preset) if preset != 'initial' else {}
preset_prepared = modules.meta_parser.parse_meta_from_preset(preset_content)
preset_content = modules.config.try_get_preset_content(
preset) if preset != 'initial' else {}
preset_prepared = modules.meta_parser.parse_meta_from_preset(
preset_content)
default_model = preset_prepared.get('base_model')
previous_default_models = preset_prepared.get('previous_default_models', [])
checkpoint_downloads = preset_prepared.get('checkpoint_downloads', {})
embeddings_downloads = preset_prepared.get('embeddings_downloads', {})
previous_default_models = preset_prepared.get(
'previous_default_models', [])
checkpoint_downloads = preset_prepared.get(
'checkpoint_downloads', {})
embeddings_downloads = preset_prepared.get(
'embeddings_downloads', {})
lora_downloads = preset_prepared.get('lora_downloads', {})
vae_downloads = preset_prepared.get('vae_downloads', {})
@ -918,7 +1102,6 @@ with shared.gradio_root:
return modules.meta_parser.load_parameter_button_click(json.dumps(preset_prepared), is_generating, inpaint_mode)
def inpaint_engine_state_change(inpaint_engine_version, *args):
if inpaint_engine_version == 'empty':
inpaint_engine_version = modules.config.default_inpaint_engine_version
@ -939,7 +1122,8 @@ with shared.gradio_root:
performance_selection.change(lambda x: [gr.update(interactive=not flags.Performance.has_restricted_features(x))] * 11 +
[gr.update(visible=not flags.Performance.has_restricted_features(x))] * 1 +
[gr.update(value=flags.Performance.has_restricted_features(x))] * 1,
[gr.update(
value=flags.Performance.has_restricted_features(x))] * 1,
inputs=performance_selection,
outputs=[
guidance_scale, sharpness, adm_scaler_end, adm_scaler_positive,
@ -947,7 +1131,8 @@ with shared.gradio_root:
scheduler_name, adaptive_cfg, refiner_swap_method, negative_prompt, disable_intermediate_results
], queue=False, show_progress=False)
output_format.input(lambda x: gr.update(output_format=x), inputs=output_format)
output_format.input(lambda x: gr.update(
output_format=x), inputs=output_format)
advanced_checkbox.change(lambda x: gr.update(visible=x), advanced_checkbox, advanced_column,
queue=False, show_progress=False) \
@ -960,7 +1145,8 @@ with shared.gradio_root:
], show_progress=False, queue=False)
# load configured default_inpaint_method
default_inpaint_ctrls = [inpaint_mode, inpaint_disable_initial_latent, inpaint_engine, inpaint_strength, inpaint_respective_field]
default_inpaint_ctrls = [inpaint_mode, inpaint_disable_initial_latent,
inpaint_engine, inpaint_strength, inpaint_respective_field]
for mode, disable_initial_latent, engine, strength, respective_field in [default_inpaint_ctrls] + enhance_inpaint_update_ctrls:
shared.gradio_root.load(inpaint_mode_change, inputs=[mode, inpaint_engine_state], outputs=[
inpaint_additional_prompt, outpaint_selections, example_inpaint_prompts, disable_initial_latent,
@ -984,13 +1170,19 @@ with shared.gradio_root:
ctrls += [base_model, refiner_model, refiner_switch] + lora_ctrls
ctrls += [input_image_checkbox, current_tab]
ctrls += [uov_method, uov_input_image]
ctrls += [outpaint_selections, inpaint_input_image, inpaint_additional_prompt, inpaint_mask_image]
ctrls += [disable_preview, disable_intermediate_results, disable_seed_increment, black_out_nsfw]
ctrls += [adm_scaler_positive, adm_scaler_negative, adm_scaler_end, adaptive_cfg, clip_skip]
ctrls += [outpaint_selections, inpaint_input_image,
inpaint_additional_prompt, inpaint_mask_image]
ctrls += [disable_preview, disable_intermediate_results,
disable_seed_increment, black_out_nsfw]
ctrls += [adm_scaler_positive, adm_scaler_negative,
adm_scaler_end, adaptive_cfg, clip_skip]
ctrls += [sampler_name, scheduler_name, vae_name]
ctrls += [overwrite_step, overwrite_switch, overwrite_width, overwrite_height, overwrite_vary_strength]
ctrls += [overwrite_upscale_strength, mixing_image_prompt_and_vary_upscale, mixing_image_prompt_and_inpaint]
ctrls += [debugging_cn_preprocessor, skipping_cn_preprocessor, canny_low_threshold, canny_high_threshold]
ctrls += [overwrite_step, overwrite_switch, overwrite_width,
overwrite_height, overwrite_vary_strength]
ctrls += [overwrite_upscale_strength,
mixing_image_prompt_and_vary_upscale, mixing_image_prompt_and_inpaint]
ctrls += [debugging_cn_preprocessor, skipping_cn_preprocessor,
canny_low_threshold, canny_high_threshold]
ctrls += [refiner_swap_method, controlnet_softness]
ctrls += freeu_ctrls
ctrls += inpaint_ctrls
@ -1006,6 +1198,7 @@ with shared.gradio_root:
enhance_input_image, enhance_checkbox, enhance_uov_method, enhance_uov_processing_order,
enhance_uov_prompt_type]
ctrls += enhance_ctrls
ctrls += bulk_enhance_ctrls
def parse_meta(raw_prompt_txt, is_generating):
loaded_json = None
@ -1020,17 +1213,21 @@ with shared.gradio_root:
return json.dumps(loaded_json), gr.update(visible=False), gr.update(visible=True)
prompt.input(parse_meta, inputs=[prompt, state_is_generating], outputs=[prompt, generate_button, load_parameter_button], queue=False, show_progress=False)
prompt.input(parse_meta, inputs=[prompt, state_is_generating], outputs=[
prompt, generate_button, load_parameter_button], queue=False, show_progress=False)
load_parameter_button.click(modules.meta_parser.load_parameter_button_click, inputs=[prompt, state_is_generating, inpaint_mode], outputs=load_data_outputs, queue=False, show_progress=False)
load_parameter_button.click(modules.meta_parser.load_parameter_button_click, inputs=[
prompt, state_is_generating, inpaint_mode], outputs=load_data_outputs, queue=False, show_progress=False)
def trigger_metadata_import(file, state_is_generating):
parameters, metadata_scheme = modules.meta_parser.read_info_from_image(file)
parameters, metadata_scheme = modules.meta_parser.read_info_from_image(
file)
if parameters is None:
print('Could not find metadata in the image!')
parsed_parameters = {}
else:
metadata_parser = modules.meta_parser.get_metadata_parser(metadata_scheme)
metadata_parser = modules.meta_parser.get_metadata_parser(
metadata_scheme)
parsed_parameters = metadata_parser.to_json(parameters)
return modules.meta_parser.load_parameter_button_click(parsed_parameters, state_is_generating, inpaint_mode)
@ -1058,7 +1255,8 @@ with shared.gradio_root:
for notification_file in ['notification.ogg', 'notification.mp3']:
if os.path.exists(notification_file):
gr.Audio(interactive=False, value=notification_file, elem_id='audio_notification', visible=False)
gr.Audio(interactive=False, value=notification_file,
elem_id='audio_notification', visible=False)
break
def trigger_describe(modes, img, apply_styles):
@ -1068,7 +1266,8 @@ with shared.gradio_root:
if flags.describe_type_photo in modes:
from extras.interrogate import default_interrogator as default_interrogator_photo
describe_prompts.append(default_interrogator_photo(img))
styles.update(["Fooocus V2", "Fooocus Enhance", "Fooocus Sharp"])
styles.update(
["Fooocus V2", "Fooocus Enhance", "Fooocus Sharp"])
if flags.describe_type_anime in modes:
from extras.wd14tagger import default_interrogator as default_interrogator_anime
@ -1098,7 +1297,6 @@ with shared.gradio_root:
if prompt == '':
return trigger_describe(mode, img, apply_styles)
return gr.update(), gr.update()
uov_input_image.upload(trigger_auto_describe, inputs=[describe_methods, uov_input_image, prompt, describe_apply_styles],
outputs=[prompt, style_selections], show_progress=True, queue=True) \
.then(fn=style_sorter.sort_styles, inputs=style_selections, outputs=style_selections, queue=False, show_progress=False) \
@ -1110,6 +1308,7 @@ with shared.gradio_root:
.then(fn=style_sorter.sort_styles, inputs=style_selections, outputs=style_selections, queue=False, show_progress=False) \
.then(lambda: None, _js='()=>{refresh_style_localization();}')
def dump_default_english_config():
from modules.localization import dump_english_config
dump_english_config(grh.all_components)
@ -1122,7 +1321,8 @@ shared.gradio_root.launch(
server_name=args_manager.args.listen,
server_port=args_manager.args.port,
share=args_manager.args.share,
auth=check_auth if (args_manager.args.share or args_manager.args.listen) and auth_enabled else None,
auth=check_auth if (
args_manager.args.share or args_manager.args.listen) and auth_enabled else None,
allowed_paths=[modules.config.path_outputs],
blocked_paths=[constants.AUTH_FILENAME]
)