mirror of
https://github.com/vladmandic/automatic
synced 2026-09-19 09:14:35 +02:00
move postprocessing scripts to accordions
Signed-off-by: Vladimir Mandic <mandic00@live.com>
This commit is contained in:
@@ -11,24 +11,21 @@ Main ToDo list can be found at [GitHub projects](https://github.com/users/vladma
|
||||
## Future Candidates
|
||||
|
||||
- Flux NF4 loader: <https://github.com/huggingface/diffusers/issues/9996>
|
||||
|
||||
## Other
|
||||
|
||||
- IPAdapter negative: <https://github.com/huggingface/diffusers/discussions/7167>
|
||||
- Control API enhance scripts compatibility
|
||||
- PixelSmith: <https://github.com/Thanos-DB/Pixelsmith>
|
||||
|
||||
## Code TODO
|
||||
|
||||
- TODO install: python 3.12.4 or higher cause a mess with pydantic (fixme)
|
||||
- TODO install: enable ROCm for windows when available (fixme)
|
||||
- TODO resize image: enable full VAE mode for resize-latent (fixme)
|
||||
- TODO processing: remove duplicate mask params (fixme)
|
||||
- TODO flux: fix loader for civitai nf4 models (fixme)
|
||||
- TODO model loader: implement model in-memory caching (fixme)
|
||||
- TODO hypertile: vae breaks when using non-standard sizes (fixme)
|
||||
- TODO model load: force-reloading entire model as loading transformers only leads to massive memory usage (fixme)
|
||||
- TODO lora load: direct with bnb (fixme)
|
||||
- TODO: lora make: support quantized flux (fixme)
|
||||
- TODO control: support scripts via api (fixme)
|
||||
- TODO modernui: monkey-patch for missing tabs.select event (fixme)
|
||||
- TODO install: python 3.12.4 or higher cause a mess with pydantic
|
||||
- TODO install: enable ROCm for windows when available
|
||||
- TODO resize image: enable full VAE mode for resize-latent
|
||||
- TODO processing: remove duplicate mask params
|
||||
- TODO flux: fix loader for civitai nf4 models
|
||||
- TODO model loader: implement model in-memory caching
|
||||
- TODO hypertile: vae breaks when using non-standard sizes
|
||||
- TODO model load: force-reloading entire model as loading transformers only leads to massive memory usage
|
||||
- TODO lora load: direct with bnb
|
||||
- TODO lora make: support quantized flux
|
||||
- TODO control: support scripts via api
|
||||
- TODO modernui: monkey-patch for missing tabs.select event
|
||||
|
||||
+32
-26
@@ -330,6 +330,7 @@ class ScriptRunner:
|
||||
self.scripts = []
|
||||
self.selectable_scripts = []
|
||||
self.alwayson_scripts = []
|
||||
self.auto_processing_scripts = []
|
||||
self.titles = []
|
||||
self.infotext_fields = []
|
||||
self.paste_field_names = []
|
||||
@@ -337,6 +338,31 @@ class ScriptRunner:
|
||||
self.is_img2img = False
|
||||
self.inputs = [None]
|
||||
|
||||
def add_script(self, script_class, path, is_img2img, is_control):
|
||||
try:
|
||||
script = script_class()
|
||||
script.filename = path
|
||||
script.is_txt2img = not is_img2img
|
||||
script.is_img2img = is_img2img
|
||||
if is_control: # this is messy but show is a legacy function that is not aware of control tab
|
||||
v1 = script.show(script.is_txt2img)
|
||||
v2 = script.show(script.is_img2img)
|
||||
if v1 == AlwaysVisible or v2 == AlwaysVisible:
|
||||
visibility = AlwaysVisible
|
||||
else:
|
||||
visibility = v1 or v2
|
||||
else:
|
||||
visibility = script.show(script.is_img2img)
|
||||
if visibility == AlwaysVisible:
|
||||
self.scripts.append(script)
|
||||
self.alwayson_scripts.append(script)
|
||||
script.alwayson = True
|
||||
elif visibility:
|
||||
self.scripts.append(script)
|
||||
self.selectable_scripts.append(script)
|
||||
except Exception as e:
|
||||
errors.log.error(f'Script initialize: {path} {e}')
|
||||
|
||||
def initialize_scripts(self, is_img2img=False, is_control=False):
|
||||
from modules import scripts_auto_postprocessing
|
||||
|
||||
@@ -351,34 +377,14 @@ class ScriptRunner:
|
||||
self.scripts.clear()
|
||||
self.alwayson_scripts.clear()
|
||||
self.selectable_scripts.clear()
|
||||
auto_processing_scripts = scripts_auto_postprocessing.create_auto_preprocessing_script_data()
|
||||
self.auto_processing_scripts = scripts_auto_postprocessing.create_auto_preprocessing_script_data()
|
||||
|
||||
all_scripts = auto_processing_scripts + scripts_data
|
||||
sorted_scripts = sorted(all_scripts, key=lambda x: x.script_class().title().lower())
|
||||
sorted_scripts = sorted(scripts_data, key=lambda x: x.script_class().title().lower())
|
||||
for script_class, path, _basedir, _script_module in sorted_scripts:
|
||||
try:
|
||||
script = script_class()
|
||||
script.filename = path
|
||||
script.is_txt2img = not is_img2img
|
||||
script.is_img2img = is_img2img
|
||||
if is_control: # this is messy but show is a legacy function that is not aware of control tab
|
||||
v1 = script.show(script.is_txt2img)
|
||||
v2 = script.show(script.is_img2img)
|
||||
if v1 == AlwaysVisible or v2 == AlwaysVisible:
|
||||
visibility = AlwaysVisible
|
||||
else:
|
||||
visibility = v1 or v2
|
||||
else:
|
||||
visibility = script.show(script.is_img2img)
|
||||
if visibility == AlwaysVisible:
|
||||
self.scripts.append(script)
|
||||
self.alwayson_scripts.append(script)
|
||||
script.alwayson = True
|
||||
elif visibility:
|
||||
self.scripts.append(script)
|
||||
self.selectable_scripts.append(script)
|
||||
except Exception as e:
|
||||
errors.log.error(f'Script initialize: {path} {e}')
|
||||
self.add_script(script_class, path, is_img2img, is_control)
|
||||
sorted_scripts = sorted(self.auto_processing_scripts, key=lambda x: x.script_class().title().lower())
|
||||
for script_class, path, _basedir, _script_module in sorted_scripts:
|
||||
self.add_script(script_class, path, is_img2img, is_control)
|
||||
|
||||
def prepare_ui(self):
|
||||
self.inputs = [None]
|
||||
|
||||
+1
-1
@@ -837,7 +837,7 @@ options_templates.update(options_section(('sampler-params', "Sampler Settings"),
|
||||
|
||||
options_templates.update(options_section(('postprocessing', "Postprocessing"), {
|
||||
'postprocessing_enable_in_main_ui': OptionInfo([], "Additional postprocessing operations", gr.Dropdown, lambda: {"multiselect":True, "choices": [x.name for x in shared_items.postprocessing_scripts()]}),
|
||||
'postprocessing_operation_order': OptionInfo([], "Postprocessing operation order", gr.Dropdown, lambda: {"multiselect":True, "choices": [x.name for x in shared_items.postprocessing_scripts()]}),
|
||||
'postprocessing_operation_order': OptionInfo([], "Postprocessing operation order", gr.Dropdown, lambda: {"multiselect":True, "choices": [x.name for x in shared_items.postprocessing_scripts()], "visible": False }),
|
||||
|
||||
"postprocessing_sep_img2img": OptionInfo("<h2>Inpaint</h2>", "", gr.HTML),
|
||||
"img2img_color_correction": OptionInfo(False, "Apply color correction"),
|
||||
|
||||
@@ -10,9 +10,10 @@ class ScriptPostprocessingCodeFormer(scripts_postprocessing.ScriptPostprocessing
|
||||
order = 3000
|
||||
|
||||
def ui(self):
|
||||
with gr.Row():
|
||||
codeformer_visibility = gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label="Strength", value=0.0, elem_id="extras_codeformer_visibility")
|
||||
codeformer_weight = gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label="Weight", value=0.2, elem_id="extras_codeformer_weight")
|
||||
with gr.Accordion('Restore faces: CodeFormer', open = False):
|
||||
with gr.Row():
|
||||
codeformer_visibility = gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label="Strength", value=0.0, elem_id="extras_codeformer_visibility")
|
||||
codeformer_weight = gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label="Weight", value=0.2, elem_id="extras_codeformer_weight")
|
||||
return { "codeformer_visibility": codeformer_visibility, "codeformer_weight": codeformer_weight }
|
||||
|
||||
def process(self, pp: scripts_postprocessing.PostprocessedImage, codeformer_visibility, codeformer_weight): # pylint: disable=arguments-differ
|
||||
|
||||
@@ -9,8 +9,9 @@ class ScriptPostprocessingGfpGan(scripts_postprocessing.ScriptPostprocessing):
|
||||
order = 2000
|
||||
|
||||
def ui(self):
|
||||
with gr.Row():
|
||||
gfpgan_visibility = gr.Slider(minimum=0.0, maximum=1.0, step=0.001, label="Strength", value=0, elem_id="extras_gfpgan_visibility")
|
||||
with gr.Accordion('Restore faces: GFPGan', open = False):
|
||||
with gr.Row():
|
||||
gfpgan_visibility = gr.Slider(minimum=0.0, maximum=1.0, step=0.001, label="Strength", value=0, elem_id="extras_gfpgan_visibility")
|
||||
return { "gfpgan_visibility": gfpgan_visibility }
|
||||
|
||||
def process(self, pp: scripts_postprocessing.PostprocessedImage, gfpgan_visibility): # pylint: disable=arguments-differ
|
||||
|
||||
@@ -10,43 +10,43 @@ class ScriptPostprocessingUpscale(scripts_postprocessing.ScriptPostprocessing):
|
||||
order = 1000
|
||||
|
||||
def ui(self):
|
||||
selected_tab = gr.State(value=0) # pylint: disable=abstract-class-instantiated
|
||||
with gr.Accordion('Postprocess Upscale', open = False):
|
||||
selected_tab = gr.State(value=0) # pylint: disable=abstract-class-instantiated
|
||||
with gr.Column():
|
||||
with gr.Row(elem_id="extras_upscale"):
|
||||
with gr.Tabs(elem_id="extras_resize_mode"):
|
||||
with gr.TabItem('Scale by', elem_id="extras_scale_by_tab") as tab_scale_by:
|
||||
upscaling_resize = gr.Slider(minimum=0.1, maximum=8.0, step=0.05, label="Resize", value=2.0, elem_id="extras_upscaling_resize")
|
||||
|
||||
with gr.Column():
|
||||
with gr.Row(elem_id="extras_upscale"):
|
||||
with gr.Tabs(elem_id="extras_resize_mode"):
|
||||
with gr.TabItem('Scale by', elem_id="extras_scale_by_tab") as tab_scale_by:
|
||||
upscaling_resize = gr.Slider(minimum=0.1, maximum=8.0, step=0.05, label="Resize", value=2.0, elem_id="extras_upscaling_resize")
|
||||
with gr.TabItem('Scale to', elem_id="extras_scale_to_tab") as tab_scale_to:
|
||||
with gr.Row():
|
||||
with gr.Row(elem_id="upscaling_column_size"):
|
||||
upscaling_resize_w = gr.Slider(minimum=64, maximum=4096, step=8, label="Width", value=1024, elem_id="extras_upscaling_resize_w")
|
||||
upscaling_resize_h = gr.Slider(minimum=64, maximum=4096, step=8, label="Height", value=1024, elem_id="extras_upscaling_resize_h")
|
||||
upscaling_res_switch_btn = ToolButton(value=symbols.switch, elem_id="upscaling_res_switch_btn")
|
||||
upscaling_crop = gr.Checkbox(label='Crop to fit', value=True, elem_id="extras_upscaling_crop")
|
||||
|
||||
with gr.TabItem('Scale to', elem_id="extras_scale_to_tab") as tab_scale_to:
|
||||
with gr.Row():
|
||||
with gr.Row(elem_id="upscaling_column_size"):
|
||||
upscaling_resize_w = gr.Slider(minimum=64, maximum=4096, step=8, label="Width", value=1024, elem_id="extras_upscaling_resize_w")
|
||||
upscaling_resize_h = gr.Slider(minimum=64, maximum=4096, step=8, label="Height", value=1024, elem_id="extras_upscaling_resize_h")
|
||||
upscaling_res_switch_btn = ToolButton(value=symbols.switch, elem_id="upscaling_res_switch_btn")
|
||||
upscaling_crop = gr.Checkbox(label='Crop to fit', value=True, elem_id="extras_upscaling_crop")
|
||||
with gr.Row():
|
||||
extras_upscaler_1 = gr.Dropdown(label='Upscaler', elem_id="extras_upscaler_1", choices=[x.name for x in shared.sd_upscalers], value=shared.sd_upscalers[0].name)
|
||||
|
||||
with gr.Row():
|
||||
extras_upscaler_1 = gr.Dropdown(label='Upscaler', elem_id="extras_upscaler_1", choices=[x.name for x in shared.sd_upscalers], value=shared.sd_upscalers[0].name)
|
||||
with gr.Row():
|
||||
extras_upscaler_2 = gr.Dropdown(label='Refine Upscaler', elem_id="extras_upscaler_2", choices=[x.name for x in shared.sd_upscalers], value=shared.sd_upscalers[0].name)
|
||||
extras_upscaler_2_visibility = gr.Slider(minimum=0.0, maximum=1.0, step=0.001, label="Upscaler 2 visibility", value=0.0, elem_id="extras_upscaler_2_visibility")
|
||||
|
||||
with gr.Row():
|
||||
extras_upscaler_2 = gr.Dropdown(label='Refine Upscaler', elem_id="extras_upscaler_2", choices=[x.name for x in shared.sd_upscalers], value=shared.sd_upscalers[0].name)
|
||||
extras_upscaler_2_visibility = gr.Slider(minimum=0.0, maximum=1.0, step=0.001, label="Upscaler 2 visibility", value=0.0, elem_id="extras_upscaler_2_visibility")
|
||||
upscaling_res_switch_btn.click(lambda w, h: (h, w), inputs=[upscaling_resize_w, upscaling_resize_h], outputs=[upscaling_resize_w, upscaling_resize_h], show_progress=False)
|
||||
tab_scale_by.select(fn=lambda: 0, inputs=[], outputs=[selected_tab])
|
||||
tab_scale_to.select(fn=lambda: 1, inputs=[], outputs=[selected_tab])
|
||||
|
||||
upscaling_res_switch_btn.click(lambda w, h: (h, w), inputs=[upscaling_resize_w, upscaling_resize_h], outputs=[upscaling_resize_w, upscaling_resize_h], show_progress=False)
|
||||
tab_scale_by.select(fn=lambda: 0, inputs=[], outputs=[selected_tab])
|
||||
tab_scale_to.select(fn=lambda: 1, inputs=[], outputs=[selected_tab])
|
||||
|
||||
return {
|
||||
"upscale_mode": selected_tab,
|
||||
"upscale_by": upscaling_resize,
|
||||
"upscale_to_width": upscaling_resize_w,
|
||||
"upscale_to_height": upscaling_resize_h,
|
||||
"upscale_crop": upscaling_crop,
|
||||
"upscaler_1_name": extras_upscaler_1,
|
||||
"upscaler_2_name": extras_upscaler_2,
|
||||
"upscaler_2_visibility": extras_upscaler_2_visibility,
|
||||
}
|
||||
return {
|
||||
"upscale_mode": selected_tab,
|
||||
"upscale_by": upscaling_resize,
|
||||
"upscale_to_width": upscaling_resize_w,
|
||||
"upscale_to_height": upscaling_resize_h,
|
||||
"upscale_crop": upscaling_crop,
|
||||
"upscaler_1_name": extras_upscaler_1,
|
||||
"upscaler_2_name": extras_upscaler_2,
|
||||
"upscaler_2_visibility": extras_upscaler_2_visibility,
|
||||
}
|
||||
|
||||
def upscale(self, image, info, upscaler, upscale_mode, upscale_by, upscale_to_width, upscale_to_height, upscale_crop):
|
||||
if upscale_mode == 1:
|
||||
|
||||
@@ -7,40 +7,41 @@ class ScriptPostprocessingUpscale(scripts_postprocessing.ScriptPostprocessing):
|
||||
name = "Video"
|
||||
|
||||
def ui(self):
|
||||
def video_type_change(video_type):
|
||||
return [
|
||||
gr.update(visible=video_type != 'None'),
|
||||
gr.update(visible=video_type == 'GIF' or video_type == 'PNG'),
|
||||
gr.update(visible=video_type == 'MP4'),
|
||||
gr.update(visible=video_type == 'MP4'),
|
||||
gr.update(visible=video_type == 'MP4'),
|
||||
gr.update(visible=video_type == 'MP4'),
|
||||
]
|
||||
with gr.Accordion('Create video', open = False):
|
||||
def video_type_change(video_type):
|
||||
return [
|
||||
gr.update(visible=video_type != 'None'),
|
||||
gr.update(visible=video_type == 'GIF' or video_type == 'PNG'),
|
||||
gr.update(visible=video_type == 'MP4'),
|
||||
gr.update(visible=video_type == 'MP4'),
|
||||
gr.update(visible=video_type == 'MP4'),
|
||||
gr.update(visible=video_type == 'MP4'),
|
||||
]
|
||||
|
||||
with gr.Row():
|
||||
gr.HTML("<span>  Video</span><br>")
|
||||
with gr.Row():
|
||||
video_type = gr.Dropdown(label='Video file', choices=['None', 'GIF', 'PNG', 'MP4'], value='None', elem_id="extras_video_type")
|
||||
duration = gr.Slider(label='Duration', minimum=0.25, maximum=10, step=0.25, value=2, visible=False, elem_id="extras_video_duration")
|
||||
with gr.Row():
|
||||
loop = gr.Checkbox(label='Loop', value=True, visible=False, elem_id="extras_video_loop")
|
||||
pad = gr.Slider(label='Pad frames', minimum=0, maximum=24, step=1, value=1, visible=False, elem_id="extras_video_pad")
|
||||
interpolate = gr.Slider(label='Interpolate frames', minimum=0, maximum=24, step=1, value=0, visible=False, elem_id="extras_video_interpolate")
|
||||
scale = gr.Slider(label='Rescale', minimum=0.5, maximum=2, step=0.05, value=1, visible=False, elem_id="extras_video_scale")
|
||||
change = gr.Slider(label='Frame change sensitivity', minimum=0, maximum=1, step=0.05, value=0.3, visible=False, elem_id="extras_video_change")
|
||||
with gr.Row():
|
||||
filename = gr.Textbox(label='Filename', placeholder='enter filename', lines=1, elem_id="extras_video_filename")
|
||||
video_type.change(fn=video_type_change, inputs=[video_type], outputs=[duration, loop, pad, interpolate, scale, change])
|
||||
return {
|
||||
"filename": filename,
|
||||
"video_type": video_type,
|
||||
"duration": duration,
|
||||
"loop": loop,
|
||||
"pad": pad,
|
||||
"interpolate": interpolate,
|
||||
"scale": scale,
|
||||
"change": change,
|
||||
}
|
||||
with gr.Row():
|
||||
gr.HTML("<span>  Video</span><br>")
|
||||
with gr.Row():
|
||||
video_type = gr.Dropdown(label='Video file', choices=['None', 'GIF', 'PNG', 'MP4'], value='None', elem_id="extras_video_type")
|
||||
duration = gr.Slider(label='Duration', minimum=0.25, maximum=10, step=0.25, value=2, visible=False, elem_id="extras_video_duration")
|
||||
with gr.Row():
|
||||
loop = gr.Checkbox(label='Loop', value=True, visible=False, elem_id="extras_video_loop")
|
||||
pad = gr.Slider(label='Pad frames', minimum=0, maximum=24, step=1, value=1, visible=False, elem_id="extras_video_pad")
|
||||
interpolate = gr.Slider(label='Interpolate frames', minimum=0, maximum=24, step=1, value=0, visible=False, elem_id="extras_video_interpolate")
|
||||
scale = gr.Slider(label='Rescale', minimum=0.5, maximum=2, step=0.05, value=1, visible=False, elem_id="extras_video_scale")
|
||||
change = gr.Slider(label='Frame change sensitivity', minimum=0, maximum=1, step=0.05, value=0.3, visible=False, elem_id="extras_video_change")
|
||||
with gr.Row():
|
||||
filename = gr.Textbox(label='Filename', placeholder='enter filename', lines=1, elem_id="extras_video_filename")
|
||||
video_type.change(fn=video_type_change, inputs=[video_type], outputs=[duration, loop, pad, interpolate, scale, change])
|
||||
return {
|
||||
"filename": filename,
|
||||
"video_type": video_type,
|
||||
"duration": duration,
|
||||
"loop": loop,
|
||||
"pad": pad,
|
||||
"interpolate": interpolate,
|
||||
"scale": scale,
|
||||
"change": change,
|
||||
}
|
||||
|
||||
def postprocess(self, images, filename, video_type, duration, loop, pad, interpolate, scale, change): # pylint: disable=arguments-differ
|
||||
filename = filename.strip() if filename is not None else ''
|
||||
|
||||
Reference in New Issue
Block a user