Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import copy
- import os
- import random
- import sys
- import traceback
- import shlex
- from modules.paths_internal import extensions_dir
- import yaml
- import platform
- import subprocess as sp
- import shutil
- import json
- import tempfile
- import gradio as gr
- import csv
- import typing
- import base64
- import io
- from PIL import Image
- import mimetypes
- mimetypes.init()
- mimetypes.add_type('application/javascript', '.js')
- import modules.generation_parameters_copypaste as parameters_copypaste
- from modules.generation_parameters_copypaste import image_from_url_text
- import modules.scripts as scripts
- from modules.processing import Processed, process_images
- from modules.shared import opts, cmd_opts, OptionInfo, hide_dirs, state
- import modules.shared as shared
- if '__file__' in locals().keys():
- root_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
- root_path = os.path.abspath(os.path.join(root_path, os.path.pardir))
- else:
- root_path = os.path.abspath(shared.script_path)
- rela_path = os.path.join('extensions')
- try:
- with open(os.path.join(extensions_dir, 'prompt_gallery_name.json')) as fd:
- extension_name = json.load(fd)['name']
- except:
- extension_name = "Prompt Gallery"
- OUTPATH_SAMPLES = os.path.join(extensions_dir, extension_name, 'assets', 'preview')
- OUTPATH_GRIDS = os.path.join(extensions_dir, extension_name, 'assets', 'grid')
- BATCH_SIZE = 2
- N_ITER = 2
- STEPS = 30
- CFG_SCALE = 11.5
- WIDTH = 512
- HEIGHT = 768
- SAMPLER_INDEX = 1
- RESTORE_FACE = 'true'
- TILING = 'false'
- DO_NOT_SAVE_GRID = 'false'
- EXCLUDED_TAGS = ['']
- global SKIP_EXISTS
- SKIP_EXISTS = True
- OUTPUTS_DICT = list()
- OUTPUTS = {}
- rawDict = {}
- qc_dict = {}
- trg_img = ''
- current_folder = ''
- def options_section_def(section_identifier, options_dict):
- ret = {}
- for k, v in options_dict.items():
- v.section = section_identifier
- ret[k] = v.default
- return ret
- pg_templates = {}
- pg_templates.update(options_section_def(('saving-images', "Saving images/grids"), {
- "samples_save": OptionInfo(True, "Always save all generated images"),
- "samples_format": OptionInfo('png', 'File format for images'),
- "samples_filename_pattern": OptionInfo("[seed]", "Images filename pattern", component_args=hide_dirs),
- "save_images_add_number": OptionInfo(True, "Add number to filename when saving", component_args=hide_dirs),
- "grid_save": OptionInfo(True, "Always save all generated image grids"),
- "grid_format": OptionInfo('png', 'File format for grids'),
- "grid_extended_filename": OptionInfo(False, "Add extended info (seed, prompt) to filename when saving grid"),
- "grid_only_if_multiple": OptionInfo(True, "Do not save grids consisting of one picture"),
- "grid_prevent_empty_spots": OptionInfo(False, "Prevent empty spots in grid (when set to autodetect)"),
- "n_rows": OptionInfo(-1, "Grid row count; use -1 for autodetect and 0 for it to be same as batch size", gr.Slider, {"minimum": -1, "maximum": 16, "step": 1}),
- "enable_pnginfo": OptionInfo(True, "Save text information about generation parameters as chunks to png files"),
- "save_txt": OptionInfo(False, "Create a text file next to every image with generation parameters."),
- "jpeg_quality": OptionInfo(80, "Quality for saved jpeg images", gr.Slider, {"minimum": 1, "maximum": 100, "step": 1}),
- "export_for_4chan": OptionInfo(True, "If PNG image is larger than 4MB or any dimension is larger than 4000, downscale and save copy as JPG"),
- "use_original_name_batch": OptionInfo(False, "Use original name for output filename during batch process in extras tab"),
- "save_selected_only": OptionInfo(True, "When using 'Save' button, only save a single selected image"),
- "do_not_add_watermark": OptionInfo(False, "Do not add watermark to images"),
- }))
- # pg_templates.update(options_section_def(('saving-paths', "Paths for saving"), {
- # "outdir_samples": OptionInfo("", "Output directory for images; if empty, defaults to three directories below", component_args=hide_dirs),
- # "outdir_txt2img_samples": OptionInfo("outputs/txt2img-images", 'Output directory for txt2img images', component_args=hide_dirs),
- # "outdir_img2img_samples": OptionInfo("outputs/img2img-images", 'Output directory for img2img images', component_args=hide_dirs),
- # "outdir_extras_samples": OptionInfo("outputs/extras-images", 'Output directory for images from extras tab', component_args=hide_dirs),
- # "outdir_grids": OptionInfo("", "Output directory for grids; if empty, defaults to two directories below", component_args=hide_dirs),
- # "outdir_txt2img_grids": OptionInfo("outputs/txt2img-grids", 'Output directory for txt2img grids', component_args=hide_dirs),
- # "outdir_img2img_grids": OptionInfo("outputs/img2img-grids", 'Output directory for img2img grids', component_args=hide_dirs),
- # "outdir_save": OptionInfo("log/images", "Directory for saving images using the Save button", component_args=hide_dirs),
- # }))
- pg_templates.update(options_section_def(('saving-to-dirs', "Saving to a directory"), {
- "save_to_dirs": OptionInfo(False, "Save images to a subdirectory"),
- "grid_save_to_dirs": OptionInfo(False, "Save grids to a subdirectory"),
- "use_save_to_dirs_for_ui": OptionInfo(False, "When using \"Save\" button, save images to a subdirectory"),
- "directories_filename_pattern": OptionInfo("", "Directory name pattern", component_args=hide_dirs),
- "directories_max_prompt_words": OptionInfo(8, "Max prompt words for [prompt_words] pattern", gr.Slider, {"minimum": 1, "maximum": 20, "step": 1, **hide_dirs}),
- }))
- pg_templates.update(options_section_def(('upscaling', "Upscaling"), {
- "ESRGAN_tile": OptionInfo(192, "Tile size for ESRGAN upscalers. 0 = no tiling.", gr.Slider, {"minimum": 0, "maximum": 512, "step": 16}),
- "ESRGAN_tile_overlap": OptionInfo(8, "Tile overlap, in pixels for ESRGAN upscalers. Low values = visible seam.", gr.Slider, {"minimum": 0, "maximum": 48, "step": 1}),
- "realesrgan_enabled_models": OptionInfo(["R-ESRGAN 4x+", "R-ESRGAN 4x+ Anime6B"], "Select which Real-ESRGAN models to show in the web UI. (Requires restart)", gr.CheckboxGroup, lambda: {"choices": realesrgan_models_names()}),
- "upscaler_for_img2img": OptionInfo(None, "Upscaler for img2img", gr.Dropdown, lambda: {"choices": [x.name for x in sd_upscalers]}),
- "use_scale_latent_for_hires_fix": OptionInfo(False, "Upscale latent space image when doing hires. fix"),
- }))
- pg_templates.update(options_section_def(('ui', "User interface"), {
- "show_progressbar": OptionInfo(True, "Show progressbar"),
- "show_progress_every_n_steps": OptionInfo(0, "Show image creation progress every N sampling steps. Set to 0 to disable. Set to -1 to show after completion of batch.", gr.Slider, {"minimum": -1, "maximum": 32, "step": 1}),
- "show_progress_grid": OptionInfo(True, "Show previews of all images generated in a batch as a grid"),
- "return_grid": OptionInfo(True, "Show grid in results for web"),
- "do_not_show_images": OptionInfo(False, "Do not show any images in results for web"),
- # "disable_weights_auto_swap": OptionInfo(False, "When reading generation parameters from text into UI (from PNG info or pasted text), do not change the selected model/checkpoint."),
- "send_seed": OptionInfo(True, "Send seed when sending prompt or image to other interface"),
- "font": OptionInfo("", "Font for image grids that have text"),
- "js_modal_lightbox": OptionInfo(True, "Enable full page image viewer"),
- "js_modal_lightbox_initially_zoomed": OptionInfo(True, "Show images zoomed in by default in full page image viewer"),
- "show_progress_in_title": OptionInfo(True, "Show generation progress in window title."),
- 'localization': OptionInfo("None", "Localization (requires restart)", gr.Dropdown, lambda: {"choices": ["None"] + list(localization.localizations.keys())}, refresh=lambda: localization.list_localizations(cmd_opts.localizations_dir)),
- }))
- map_sampler_to_idx = {
- 'Euler a': 0,
- 'Euler': 1,
- 'LMS': 2,
- 'Heun': 3,
- 'DPM2': 4,
- 'DPM2 a': 5,
- 'DPM fast': 6,
- 'DPM adaptive': 7,
- 'LMS Karras': 8,
- 'DPM2 Karras': 9,
- 'DPM2 a Karras': 10,
- 'DDIM': 11,
- 'PLMS': 12,
- 'DPM++ 2S a Karras': 13,
- 'DPM++ 2M Karras': 14,
- 'DPM++ SDE Karras': 15}
- map_keys = {
- "value": "prompt",
- "negative": "negative_prompt"}
- map_param = {
- "sd_model": "sd_model",
- "outpath_samples": "outpath_samples",
- "outpath_grids": "outpath_grids",
- "prompt_for_display": "prompt_for_display",
- "styles": "styles",
- "Seed": "seed",
- "Variation seed strength": "subseed_strength",
- "Variation seed": "subseed",
- "seed_resize_from_h": "seed_resize_from_h",
- "seed_resize_from_w": "seed_resize_from_w",
- "Sampler": "sampler_index",
- "batch_size": "batch_size",
- "n_iter": "n_iter",
- "Steps": "steps",
- "CFG scale": "cfg_scale",
- "width": "width",
- "height": "height",
- "restore_faces": "restore_faces",
- "tiling": "tiling",
- "do_not_save_samples": "do_not_save_samples",
- "do_not_save_grid": "do_not_save_grid"}
- def process_string_tag(tag):
- return tag
- def process_int_tag(tag):
- return int(tag)
- def process_float_tag(tag):
- return float(tag)
- def process_boolean_tag(tag):
- return True if (tag == "true") else False
- prompt_tags = {
- "sd_model": None,
- "outpath_samples": process_string_tag,
- "outpath_grids": process_string_tag,
- "prompt_for_display": process_string_tag,
- "prompt": process_string_tag,
- "negative_prompt": process_string_tag,
- "styles": process_string_tag,
- "seed": process_int_tag,
- "subseed_strength": process_float_tag,
- "subseed": process_int_tag,
- "seed_resize_from_h": process_int_tag,
- "seed_resize_from_w": process_int_tag,
- "sampler_index": process_int_tag,
- "batch_size": process_int_tag,
- "n_iter": process_int_tag,
- "steps": process_int_tag,
- "cfg_scale": process_float_tag,
- "width": process_int_tag,
- "height": process_int_tag,
- "restore_faces": process_boolean_tag,
- "tiling": process_boolean_tag,
- "do_not_save_samples": process_boolean_tag,
- "do_not_save_grid": process_boolean_tag
- }
- avatar_prompts = list()
- avatar_names = list()
- avatar_negatives = list()
- avatar_name = ""
- def cmdargs(line):
- args = shlex.split(line)
- args[args.index('--outpath_samples')+1] = args[args.index('--outpath_samples')+1][:-1]
- args[args.index('--outpath_grids')+1] = args[args.index('--outpath_grids')+1][:-1]
- pos = 0
- res = {}
- while pos < len(args):
- arg = args[pos]
- assert arg.startswith("--"), f'must start with "--": {arg}'
- tag = arg[2:]
- func = prompt_tags.get(tag, None)
- assert func, f'unknown commandline option: {arg}'
- assert pos+1 < len(args), f'missing argument for command line option {arg}'
- val = args[pos+1]
- res[tag] = func(val)
- pos += 2
- return res
- def add_param(key, value, cur_str):
- cur_str += '--{key} {value} '.format(key=key, value=value)
- return cur_str
- def parse_size(i_width, i_height, str_size, cur_str):
- i_width = str_size.split('x')[0]
- i_height = str_size.split('x')[1]
- def parse_virariant_size(str_size, cur_str):
- width = str_size.split('x')[0]
- height = str_size.split('x')[1]
- cur_str = add_param('seed_resize_from_w', width, cur_str)
- cur_str = add_param('seed_resize_from_h', height, cur_str)
- return cur_str
- def parse_param(param_str):
- m_batch_size = BATCH_SIZE
- m_n_iter = N_ITER
- m_steps = STEPS
- m_cfg_scale = CFG_SCALE
- m_width = WIDTH
- m_height = HEIGHT
- m_sampler_index = SAMPLER_INDEX
- # m_tiling = TILING
- m_restore_faces = RESTORE_FACE
- m_do_not_save_grid = DO_NOT_SAVE_GRID
- # m_sd_model = sd_model
- cur_line = ""
- for item in param_str.split(', '):
- if item == '':
- continue
- group = item.split(': ')
- key = group[0]
- value = group[1]
- if key == 'Steps':
- m_steps = value
- elif key == "CFG scale":
- m_cfg_scale = value
- elif key == 'Sampler':
- m_sampler_index = map_sampler_to_idx[value]
- elif key == 'Size':
- parse_size(m_width, m_height, value, cur_line)
- elif key == 'Seed resize from':
- cur_line = parse_virariant_size(value, cur_line)
- elif key == 'Seed':
- cur_line = add_param("seed", value, cur_line)
- elif key == 'Variation seed strength':
- cur_line = add_param("subseed_strength", value, cur_line)
- elif key == 'Variation seed':
- cur_line = add_param("subseed", value, cur_line)
- # elif key == 'Model hash':
- # cur_line = add_param("sd_model", m_sd_model, cur_line)
- cur_line = add_param("batch_size", m_batch_size, cur_line)
- cur_line = add_param("n_iter", m_n_iter, cur_line)
- cur_line = add_param("steps", m_steps, cur_line)
- cur_line = add_param("cfg_scale", m_cfg_scale, cur_line)
- cur_line = add_param("sampler_index", m_sampler_index, cur_line)
- cur_line = add_param("width", m_width, cur_line)
- cur_line = add_param("height", m_height, cur_line)
- cur_line = add_param("restore_faces", m_restore_faces, cur_line)
- # cur_line = add_param("tiling", m_tiling, cur_line)
- cur_line = add_param("do_not_save_grid", m_do_not_save_grid, cur_line)
- return cur_line
- def parse_yaml_dict(rawDict, tag, avatar_prompt, avatar_name, default_negative):
- # depth-first-search
- if 'value' in rawDict.keys() or 'negative' in rawDict.keys():
- if SKIP_EXISTS:
- if os.path.exists(os.path.join(OUTPATH_SAMPLES, tag, avatar_name+'.png')) or os.path.exists(os.path.join(OUTPATH_SAMPLES,tag,'Not-available.png')):
- print("Skip "+str(tag))
- return ""
- cur = ""
- parsed_param = False
- m_positive = avatar_prompt
- m_negative = default_negative
- for item in rawDict.items():
- key = item[0]
- value = item[1]
- if key == 'param':
- params = parse_param(rawDict['param'])
- parsed_param = True
- elif key == 'value':
- m_positive = value + m_positive
- elif key == 'negative':
- m_negative = value +','+ m_negative
- cur += "--{key} \"{value}\" ".format(key='prompt', value= m_positive)
- cur += "--{key} \"{value}\" ".format(key='negative_prompt', value= m_negative)
- if parsed_param == False:
- params = parse_param("")
- cur += params
- cur += '--outpath_samples \"{} \"'.format(str(os.path.join(OUTPATH_SAMPLES, str(tag), '')))
- cur += ' --outpath_grids \"{} \"'.format(str(os.path.join(OUTPATH_GRIDS, str(tag), '')))
- return cur
- else:
- for item in rawDict.items():
- key = item[0]
- ret = parse_yaml_dict(rawDict[key], tag if key=='' else key, avatar_prompt, avatar_name, default_negative)
- if len(ret) != 0:
- if tag not in EXCLUDED_TAGS:
- OUTPUTS_DICT.append({'name': key,
- 'prompt': item[1]['value'] if 'value' in item[1].keys() else '',
- 'negative_prompt': item[1]['negative'] if 'negative' in item[1].keys() else ''})
- if tag in OUTPUTS.keys():
- OUTPUTS[tag].append(ret)
- else:
- OUTPUTS[tag] = [ret]
- return ""
- def rename_preview(avatar_name):
- if avatar_name == '':
- print("Please select avatar name first.")
- return
- root = OUTPATH_SAMPLES
- for folder in os.listdir(root):
- files = os.listdir(os.path.join(root, folder))
- if 'Not-available.png' in files:
- print('Skip '+ folder + ' not available.')
- continue
- if avatar_name + '.png' in files:
- continue
- for each_avatar in avatar_names:
- if each_avatar + '.png' in files:
- files.remove(each_avatar + '.png')
- if len(files) == 1:
- os.rename(os.path.join(root, folder, files[0]), os.path.join(root, folder, avatar_name + '.png'))
- else:
- print('There are 0 or more than 1 files in ' + folder)
- def load_prompt_file(file):
- if (file is None):
- lines = []
- else:
- lines = [x.strip() for x in file.decode('utf8', errors='ignore').split("\n")]
- return None, "\n".join(lines), gr.update(lines=7)
- def copy_from_prompt_app():
- return []
- def open_folder(f):
- if not os.path.exists(f):
- print(f'Folder "{f}" does not exist. After you create an image, the folder will be created.')
- return
- elif not os.path.isdir(f):
- 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
- 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])
- class PromptStyle(typing.NamedTuple):
- name: str
- prompt: str
- negative_prompt: str
- def save_styles() -> None:
- if len(OUTPUTS.keys()) == 0:
- return
- path = os.path.join('./', 'styles.csv')
- # Write to temporary file first, so we don't nuke the file if something goes wrong
- fd, temp_path = tempfile.mkstemp(".csv")
- with os.fdopen(fd, "a", encoding="utf-8-sig", newline='') as file:
- # _fields is actually part of the public API: typing.NamedTuple is a replacement for collections.NamedTuple,
- # and collections.NamedTuple has explicit documentation for accessing _fields. Same goes for _asdict()
- writer = csv.DictWriter(file, fieldnames=PromptStyle._fields)
- writer.writeheader()
- for row in OUTPUTS_DICT:
- writer.writerow({'name': row['name'], 'prompt': row['prompt'], 'negative_prompt': row['negative_prompt']})
- # writer.writerows(style._asdict() for k, style in self.styles.items())
- # Always keep a backup file around
- if os.path.exists(path) and not os.path.exists(path + ".bak"):
- shutil.move(path, path + ".bak")
- shutil.move(temp_path, path)
- def load_prompt(file, default_negative, dropdown, skip_exist):
- global SKIP_EXISTS
- SKIP_EXISTS = skip_exist
- if dropdown == '' or file is None:
- return
- rawDict = yaml.load(file, Loader = yaml.BaseLoader)
- default_negative = default_negative + ',' + avatar_negatives[avatar_names.index(dropdown)]
- parse_yaml_dict(rawDict, "", avatar_prompts[avatar_names.index(dropdown)], dropdown, default_negative)
- prompt_txt = ""
- keys = list(filter(lambda x: x not in EXCLUDED_TAGS, OUTPUTS.keys()))
- for style in keys:
- for each_line in OUTPUTS[style]:
- prompt_txt += each_line + '\n'
- return [prompt_txt, gr.Row.update(visible=True)]
- def load_avartar(avatar_dict, customize_tags_positive):
- avatars = yaml.load(avatar_dict, yaml.BaseLoader)
- for name, prompt in avatars.items():
- avatar_names.append(name)
- if 'value' in prompt.keys():
- avatar_prompts.append(customize_tags_positive + ', ' + prompt['value'])
- else:
- avatar_prompts.append(customize_tags_positive + ', ' + '')
- if 'negative' in prompt.keys():
- avatar_negatives.append(prompt['negative'])
- else:
- avatar_negatives.append('')
- return [gr.Dropdown.update(choices=avatar_names, value=avatar_names[0]), gr.Column.update(visible=True), gr.Group.update(visible=True)]
- def scan_outputs(avatar_name):
- if avatar_name is None or len(avatar_name) == 0:
- print("Please select avatar name first.")
- return
- root = OUTPATH_SAMPLES
- global qc_dict
- qc_dict = {}
- if not os.path.exists(root):
- os.mkdir(root)
- for folder in os.listdir(root):
- if os.path.isdir(os.path.join(root, folder)) == False:
- continue
- files = os.listdir(os.path.join(root, folder))
- if 'Not-available.png' in files:
- print('Skip '+ folder + ' not available.')
- continue
- if avatar_name + '.png' in files:
- continue
- for each_avatar in avatar_names:
- if each_avatar + '.png' in files:
- files.remove(each_avatar + '.png')
- if len(files) == 0:
- continue
- # print("Insert file:")
- for file in files:
- print(os.path.join(root, folder, file))
- qc_dict[folder] = [os.path.join(root, folder, file) for file in files]
- if len(qc_dict.keys()) == 0:
- return gr.Dropdown.update(choices=[])
- return gr.Dropdown.update(choices=list(qc_dict.keys()), value=list(qc_dict.keys())[0])
- def update_gallery(dropdown, avatar):
- root = OUTPATH_SAMPLES
- global trg_img, current_folder
- current_folder = os.path.join(root, dropdown)
- trg_img = os.path.join(root, dropdown, avatar + '.png')
- # print("Detected folders:")
- # print(qc_dict)
- # print("Selected folder:")
- # print(dropdown)
- # print("Detected files:")
- # print(qc_dict[dropdown])
- return qc_dict[dropdown]
- def clean_select_picture(filename):
- if current_folder == '':
- print("Please select qc tag.")
- return
- for file in os.listdir(current_folder):
- is_avatar = False
- for each_avatar in avatar_names:
- if each_avatar + '.png' == file:
- is_avatar = True
- break
- if '-' in file and file.split('.')[0] in filename:
- print("rename", os.path.join(current_folder, file), trg_img)
- os.rename(os.path.join(current_folder, file), trg_img)
- elif is_avatar == False:
- print(file, "delete", os.path.join(current_folder, file))
- os.remove(os.path.join(current_folder, file))
- def image_url(filedata):
- if type(filedata) == list:
- if len(filedata) == 0:
- return None
- filedata = filedata[0]
- # for item in filedata:
- # if filedata["is_file"]:
- # filedata = item
- # 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'
- # image = Image.open(filename)
- # clean_select_picture(os.path.basename(filename))
- # return Image.open(filename)
- 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'
- image = Image.open(filename)
- clean_select_picture(os.path.basename(filename))
- return Image.open(filename)
- elif type(filedata) == dict:
- print(filedata)
- print("Dict is not file.")
- return
- elif type(filedata) != dict and 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
- return None
- def dropdown_change():
- global OUTPUTS, OUTPUTS_DICT
- default_negative = []
- OUTPUTS = {}
- OUTPUTS_DICT = []
- return [ gr.File.update(value=None), gr.Textbox.update(value=None)]
- class Script(scripts.Script):
- def title(self):
- return "Prompt gallery"
- def ui(self, is_img2img):
- with gr.Group():
- with gr.Column():
- label_avatar = gr.Label("Upload avatars config")
- avatar_dict = gr.File(label="Upload avatar prompt inputs", type='bytes')
- # copy_from_app_button = gr.Button("Copy From Prompt Preview")
- with gr.Group():
- with gr.Column(visible=False) as avatar_col:
- label_presets = gr.Label("Presets")
- dropdown = gr.Dropdown(label="Choose avatar", choices=[""], value="", type="value", elem_id="dropdown")
- dropdown.save_to_config = True
- with gr.Row():
- checkbox_iterate = gr.Checkbox(label="Iterate seed every line", value=False)
- skip_exist = gr.Checkbox(value=True, label="skip exist")
- default_negative = gr.Textbox(label="default_negative", lines=1)
- default_positive = gr.Textbox(label="default_positive", lines=1)
- prompt_dict = gr.File(label="Upload prompt dictionary", type='bytes')
- with gr.Row(visible = False) as save_prompts:
- open_button = gr.Button("Open outputs directory")
- export_button = gr.Button("Export to WebUI style")
- prompt_display = gr.Textbox(label="List of prompt inputs", lines=1)
- prompt_dict.change(fn=load_prompt, inputs=[prompt_dict, default_negative, dropdown, skip_exist], outputs=[prompt_display, save_prompts])
- open_button.click(fn=lambda: open_folder(OUTPATH_SAMPLES), inputs=[], outputs=[])
- export_button.click(fn=save_styles, inputs=[], outputs=[])
- with gr.Group(visible=False) as qc_widgets:
- label_preview = gr.Label("QC preview")
- with gr.Row():
- qc_refresh = gr.Button("QC scan")
- preview_dropdown = gr.Dropdown(label="Select prompts", choices=[""], value="", type="value", elem_id="dropdown")
- preview_gallery = gr.Gallery(label='Output', show_label=False, elem_id=f"preview_gallery").style(grid=4)
- qc_refresh.click(fn=scan_outputs, inputs=[dropdown], outputs=preview_dropdown)
- with gr.Row():
- qc_show = gr.Button(f"Show pics")
- qc_select = gr.Button(f"Select")
- rename_button = gr.Button("Auto rename")
- selected_img = gr.Image(label="Selected",show_label=False, source="upload", interactive=True, type="pil").style(height=480)
- qc_show.click(fn=update_gallery, inputs=[preview_dropdown, dropdown], outputs=preview_gallery)
- qc_select.click(
- fn=lambda x: image_url(x),
- _js="extract_image_from_gallery",
- inputs=[preview_gallery],
- outputs=[selected_img],
- )
- # qc_select.click(fn=select_picture, inputs=[dropdown, preview_dropdown, preview_gallery], outputs=[])
- dropdown.change(fn=dropdown_change, inputs=[], outputs=[prompt_dict, prompt_display])
- rename_button.click(fn=rename_preview, inputs=[dropdown], outputs=[])
- # qc_select.click(fn=scan_outputs, inputs=[], outputs=[preview_dropdown])
- avatar_dict.change(fn=load_avartar, inputs=[avatar_dict, default_positive], outputs=[dropdown, avatar_col, qc_widgets])
- return [checkbox_iterate, avatar_dict, prompt_dict, default_negative, default_positive, dropdown, prompt_display, rename_button, label_avatar, open_button, export_button, skip_exist, label_presets, label_preview, preview_dropdown, preview_gallery, qc_select, qc_refresh, qc_show, selected_img]
- def run(self, p, checkbox_iterate, avatar_dict, prompt_dict, default_negative, default_positive, dropdown, prompt_display, rename_button, label_avatar, open_button, export_button, skip_exist, label_presets, label_preview, preview_dropdown, preview_gallery, qc_select, qc_refresh, qc_show, selected_img):
- global pg_templates
- backup = copy.deepcopy(shared.opts)
- shared.opts.data.update(pg_templates)
- lines = [x.strip() for x in prompt_display.splitlines()]
- lines = [x for x in lines if len(x) > 0]
- p.do_not_save_grid = True
- job_count = 0
- jobs = []
- for line in lines:
- if "--" in line:
- try:
- args = cmdargs(line)
- except Exception:
- print(f"Error parsing line [line] as commandline:", file=sys.stderr)
- print(traceback.format_exc(), file=sys.stderr)
- args = {"prompt": line}
- else:
- args = {"prompt": line}
- n_iter = args.get("n_iter", 1)
- if n_iter != 1:
- job_count += n_iter
- else:
- job_count += 1
- jobs.append(args)
- # print(f"Will process {len(lines)} lines in {job_count} jobs.")
- if (checkbox_iterate and p.seed == -1):
- p.seed = int(random.randrange(4294967294))
- state.job_count = job_count
- images = []
- for n, args in enumerate(jobs):
- state.job = f"{state.job_no + 1} out of {state.job_count}"
- copy_p = copy.copy(p)
- for k, v in args.items():
- setattr(copy_p, k, v)
- proc = process_images(copy_p)
- images += proc.images
- if (checkbox_iterate):
- p.seed = p.seed + (p.batch_size * p.n_iter)
- OUTPUTS = {}
- rawDict = {}
- shared.opts = backup
- return Processed(p, images, p.seed, "")
Add Comment
Please, Sign In to add comment