mirror of
https://github.com/vladmandic/automatic
synced 2026-09-19 01:04:32 +02:00
remove process preview
Co-authored-by: Copilot <copilot@github.com> Signed-off-by: Vladimir Mandic <mandic00@live.com>
This commit is contained in:
@@ -1,5 +1,11 @@
|
||||
# Change Log for SD.Next
|
||||
|
||||
## Update for 2026-04-29
|
||||
|
||||
- **Control**
|
||||
- remove "processed preview" from ui
|
||||
preprocessor output can still be generated by clicking preview button in in control unit and it will render into normal output area
|
||||
|
||||
## Update for 2026-04-28
|
||||
|
||||
### Highlights for 2026-04-28
|
||||
|
||||
@@ -386,7 +386,9 @@ class Processor:
|
||||
def preview(self):
|
||||
import modules.ui_control_helpers as helpers
|
||||
input_image = helpers.input_source
|
||||
if input_image is None:
|
||||
return []
|
||||
if isinstance(input_image, list):
|
||||
input_image = input_image[0]
|
||||
debug('Control process preview')
|
||||
return self.__call__(input_image)
|
||||
return [self.__call__(input_image)]
|
||||
|
||||
+11
-15
@@ -39,7 +39,7 @@ def test_processors(image):
|
||||
draw.text((10, 10), processor_id, (0,0,0), font=font)
|
||||
draw.text((8, 8), processor_id, (255,255,255), font=font)
|
||||
res.append(output)
|
||||
yield output, None, None, res
|
||||
yield output, None, res
|
||||
rows = round(math.sqrt(len(res)))
|
||||
cols = math.ceil(len(res) / rows)
|
||||
w, h = 256, 256
|
||||
@@ -52,8 +52,7 @@ def test_processors(image):
|
||||
thumb = image.copy().convert('RGB')
|
||||
thumb.thumbnail((w, h), Image.Resampling.HAMMING)
|
||||
grid.paste(thumb, box=(x, y))
|
||||
yield None, grid, None, res
|
||||
return None, grid, None, res # preview_process, output_image, output_video, output_gallery
|
||||
yield None, grid, res
|
||||
|
||||
|
||||
def test_controlnets(prompt, negative, image):
|
||||
@@ -90,7 +89,7 @@ def test_controlnets(prompt, negative, image):
|
||||
draw.text((10, 10), model_id, (0,0,0), font=font)
|
||||
draw.text((8, 8), model_id, (255,255,255), font=font)
|
||||
res.append(output)
|
||||
yield output, None, None, res
|
||||
yield output, None, res
|
||||
rows = round(math.sqrt(len(res)))
|
||||
cols = math.ceil(len(res) / rows)
|
||||
w, h = 256, 256
|
||||
@@ -103,8 +102,7 @@ def test_controlnets(prompt, negative, image):
|
||||
thumb = image.copy().convert('RGB')
|
||||
thumb.thumbnail((w, h), Image.Resampling.HAMMING)
|
||||
grid.paste(thumb, box=(x, y))
|
||||
yield None, grid, None, res
|
||||
return None, grid, None, res # preview_process, output_image, output_video, output_gallery
|
||||
yield grid, None, res
|
||||
|
||||
|
||||
def test_adapters(prompt, negative, image):
|
||||
@@ -142,7 +140,7 @@ def test_adapters(prompt, negative, image):
|
||||
draw.text((10, 10), model_id, (0,0,0), font=font)
|
||||
draw.text((8, 8), model_id, (255,255,255), font=font)
|
||||
res.append(output)
|
||||
yield output, None, None, res
|
||||
yield output, None, res
|
||||
rows = round(math.sqrt(len(res)))
|
||||
cols = math.ceil(len(res) / rows)
|
||||
w, h = 256, 256
|
||||
@@ -155,8 +153,7 @@ def test_adapters(prompt, negative, image):
|
||||
thumb = image.copy().convert('RGB')
|
||||
thumb.thumbnail((w, h), Image.Resampling.HAMMING)
|
||||
grid.paste(thumb, box=(x, y))
|
||||
yield None, grid, None, res
|
||||
return None, grid, None, res # preview_process, output_image, output_video, output_gallery
|
||||
yield grid, None, res
|
||||
|
||||
|
||||
def test_xs(prompt, negative, image):
|
||||
@@ -193,7 +190,7 @@ def test_xs(prompt, negative, image):
|
||||
draw.text((10, 10), model_id, (0,0,0), font=font)
|
||||
draw.text((8, 8), model_id, (255,255,255), font=font)
|
||||
res.append(output)
|
||||
yield output, None, None, res
|
||||
yield output, None, res
|
||||
rows = round(math.sqrt(len(res)))
|
||||
cols = math.ceil(len(res) / rows)
|
||||
w, h = 256, 256
|
||||
@@ -206,8 +203,7 @@ def test_xs(prompt, negative, image):
|
||||
thumb = image.copy().convert('RGB')
|
||||
thumb.thumbnail((w, h), Image.Resampling.HAMMING)
|
||||
grid.paste(thumb, box=(x, y))
|
||||
yield None, grid, None, res
|
||||
return None, grid, None, res # preview_process, output_image, output_video, output_gallery
|
||||
yield grid, None, res
|
||||
|
||||
|
||||
def test_lite(prompt, negative, image):
|
||||
@@ -245,7 +241,7 @@ def test_lite(prompt, negative, image):
|
||||
draw.text((10, 10), model_id, (0,0,0), font=font)
|
||||
draw.text((8, 8), model_id, (255,255,255), font=font)
|
||||
res.append(output)
|
||||
yield output, None, None, res
|
||||
yield output, None, res
|
||||
rows = round(math.sqrt(len(res)))
|
||||
cols = math.ceil(len(res) / rows)
|
||||
w, h = 256, 256
|
||||
@@ -258,5 +254,5 @@ def test_lite(prompt, negative, image):
|
||||
thumb = image.copy().convert('RGB')
|
||||
thumb.thumbnail((w, h), Image.Resampling.HAMMING)
|
||||
grid.paste(thumb, box=(x, y))
|
||||
yield None, grid, None, res
|
||||
return None, grid, None, res # preview_process, output_image, output_video, output_gallery
|
||||
yield grid, None, res
|
||||
return grid, None, res # preview_process, output_image, output_video, output_gallery
|
||||
|
||||
@@ -80,7 +80,6 @@ class History:
|
||||
break
|
||||
current_index -= 1
|
||||
if item.latent is None:
|
||||
print('HERE')
|
||||
return None, -1
|
||||
log.debug(f'History get: index={current_index} time={item.ts} shape={list(item.latent.shape)} dtype={item.latent.dtype} count={self.count}')
|
||||
return item.latent.to(devices.device), current_index
|
||||
|
||||
+6
-6
@@ -290,9 +290,9 @@ def run_rembg(input_image: Image.Image, input_mask: np.ndarray):
|
||||
'alpha_matting_foreground_threshold': 240,
|
||||
'alpha_matting_background_threshold': 10,
|
||||
'alpha_matting_erode_size': int(opts.mask_erode * 40),
|
||||
'session': rembg.new_session(opts.model),
|
||||
'session': rembg.new_session(opts.model), # pylint: disable=c-extension-no-member
|
||||
}
|
||||
mask = rembg.remove(**args)
|
||||
mask = rembg.remove(**args) # pylint: disable=c-extension-no-member
|
||||
mask = np.array(mask)
|
||||
if input_mask is None:
|
||||
input_mask = np.zeros(mask.shape, dtype='uint8')
|
||||
@@ -574,13 +574,13 @@ def create_segment_ui():
|
||||
return controls
|
||||
|
||||
|
||||
def bind_controls(image_controls: list[gr.Image], preview_image: gr.Image, output_image: gr.Image):
|
||||
def bind_controls(image_controls: list[gr.Image], output_image: gr.Image):
|
||||
for image_control in image_controls:
|
||||
btn_mask.click(run_mask, inputs=[image_control], outputs=[preview_image])
|
||||
btn_mask.click(run_mask, inputs=[image_control], outputs=[output_image])
|
||||
btn_lama.click(run_lama, inputs=[image_control], outputs=[output_image])
|
||||
image_control.edit(fn=run_mask_live, inputs=[image_control], outputs=[preview_image])
|
||||
image_control.edit(fn=run_mask_live, inputs=[image_control], outputs=[output_image])
|
||||
for control in controls:
|
||||
control.change(fn=run_mask_live, inputs=[image_control], outputs=[preview_image])
|
||||
control.change(fn=run_mask_live, inputs=[image_control], outputs=[output_image])
|
||||
|
||||
|
||||
def process_kanvas(kanvas_data):
|
||||
|
||||
+14
-23
@@ -56,11 +56,11 @@ def return_controls(res, t: float | None = None):
|
||||
else:
|
||||
perf = return_stats(t)
|
||||
if res is None: # no response
|
||||
return [None, None, None, None, '', perf]
|
||||
return [None, None, None, '', perf]
|
||||
elif isinstance(res, str): # error response
|
||||
return [None, None, None, None, res, perf]
|
||||
return [None, None, None, res, perf]
|
||||
elif isinstance(res, tuple): # standard response received as tuple via control_run->yield(output_images, process_image, result_txt)
|
||||
preview_image = res[1] # may be None
|
||||
_preview_image = res[1] # may be None
|
||||
output_image = res[0][0] if isinstance(res[0], list) else res[0] # may be image or list of images
|
||||
if isinstance(res[0], list):
|
||||
output_gallery = res[0] if res[0][0] is not None else []
|
||||
@@ -68,9 +68,9 @@ def return_controls(res, t: float | None = None):
|
||||
output_gallery = [res[0]] if res[0] is not None else [] # must return list, but can receive single image
|
||||
result_txt = res[2] if len(res) > 2 else '' # do we have a message
|
||||
output_video = res[3] if len(res) > 3 else None # do we have a video filename
|
||||
return [preview_image, output_image, output_video, output_gallery, result_txt, perf]
|
||||
return [output_image, output_video, output_gallery, result_txt, perf]
|
||||
else: # unexpected
|
||||
return [None, None, None, None, f'Control: Unexpected response: {type(res)}', perf]
|
||||
return [None, None, None, f'Control: Unexpected response: {type(res)}', perf]
|
||||
|
||||
|
||||
def get_units(*values):
|
||||
@@ -168,7 +168,6 @@ def create_ui(_blocks: gr.Blocks=None):
|
||||
with gr.Accordion(open=False, label="Input", elem_id="control_input", elem_classes=["small-accordion"]):
|
||||
with gr.Row():
|
||||
show_input = gr.Checkbox(label="Show input", value=True, elem_id="control_show_input")
|
||||
show_preview = gr.Checkbox(label="Show preview", value=False, elem_id="control_show_preview")
|
||||
with gr.Row():
|
||||
input_type = gr.Radio(label="Control input type", choices=['Control only', 'Init image same as control', 'Separate init image'], value='Control only', type='index', elem_id='control_input_type')
|
||||
with gr.Row():
|
||||
@@ -259,15 +258,9 @@ def create_ui(_blocks: gr.Blocks=None):
|
||||
output_image = gr.Image(label="Output", show_label=False, type="pil", interactive=False, tool="editor", height=gr_height, elem_id='control_output_image', elem_classes=['control-image'])
|
||||
with gr.Tab('Video', id='out-video'):
|
||||
output_video = gr.Video(label="Output", show_label=False, height=gr_height, elem_id='control_output_video', elem_classes=['control-image'])
|
||||
with gr.Column(scale=9, elem_id='control-preview-column', visible=False) as column_preview:
|
||||
gr.HTML('<span id="control-preview-button">Preview</p>')
|
||||
with gr.Tabs(elem_classes=['control-tabs'], elem_id='control-tab-preview'):
|
||||
with gr.Tab('Preview', id='preview-image') as _tab_preview:
|
||||
preview_process = gr.Image(label="Preview", show_label=False, type="pil", interactive=False, height=gr_height, visible=True, elem_id='control_preview', elem_classes=['control-image'])
|
||||
|
||||
|
||||
from modules.ui_control_elements import create_ui_elements
|
||||
create_ui_elements(units, result_txt, preview_process)
|
||||
create_ui_elements(units, result_txt, output_gallery)
|
||||
|
||||
with gr.Row(elem_id="control_script_container"):
|
||||
input_script_args = scripts_manager.scripts_current.setup_ui(parent='control', accordion=True)
|
||||
@@ -284,7 +277,6 @@ def create_ui(_blocks: gr.Blocks=None):
|
||||
btn_update.click(fn=get_units, inputs=controls, outputs=[], show_progress='hidden', queue=False)
|
||||
|
||||
show_input.change(fn=lambda x: gr.update(visible=x), inputs=[show_input], outputs=[column_input])
|
||||
show_preview.change(fn=lambda x: gr.update(visible=x), inputs=[show_preview], outputs=[column_preview])
|
||||
input_type.change(fn=lambda x: gr.update(visible=x == 2), inputs=[input_type], outputs=[column_init])
|
||||
btn_prompt_counter.click(
|
||||
fn=call_queue.wrap_queued_call(ui_common.update_token_counter),
|
||||
@@ -303,7 +295,7 @@ def create_ui(_blocks: gr.Blocks=None):
|
||||
fn=helpers.select_input,
|
||||
_js="controlInputMode",
|
||||
inputs=[input_mode, input_image, init_image, input_type, input_video, input_batch, input_folder],
|
||||
outputs=[output_tabs, preview_process, result_txt, width_before, height_before],
|
||||
outputs=[output_tabs, result_txt, width_before, height_before],
|
||||
show_progress='hidden',
|
||||
queue=False,
|
||||
)
|
||||
@@ -345,7 +337,6 @@ def create_ui(_blocks: gr.Blocks=None):
|
||||
override_script_name, override_script_args, override_settings,
|
||||
]
|
||||
output_fields = [
|
||||
preview_process,
|
||||
output_image,
|
||||
output_video,
|
||||
output_gallery,
|
||||
@@ -470,9 +461,9 @@ def create_ui(_blocks: gr.Blocks=None):
|
||||
generation_parameters_copypaste.register_paste_params_button(bindings)
|
||||
|
||||
if (installer.version['kanvas'] == 'disabled') or (installer.version['kanvas'] == 'unavailable'):
|
||||
masking.bind_controls([input_image], preview_process, output_image)
|
||||
masking.bind_controls([input_image], output_image)
|
||||
else:
|
||||
masking.bind_kanvas(input_image, preview_process)
|
||||
masking.bind_kanvas(input_image, output_image)
|
||||
|
||||
if os.environ.get('SD_CONTROL_DEBUG', None) is not None: # debug only
|
||||
from modules.control.test import test_processors, test_controlnets, test_adapters, test_xs, test_lite
|
||||
@@ -484,11 +475,11 @@ def create_ui(_blocks: gr.Blocks=None):
|
||||
run_test_adapters_btn = gr.Button(value="Test:Adapters", variant='primary', elem_classes=['control-button'])
|
||||
run_test_lite_btn = gr.Button(value="Test:Control-LLLite", variant='primary', elem_classes=['control-button'])
|
||||
|
||||
run_test_processors_btn.click(fn=test_processors, inputs=[input_image], outputs=[preview_process, output_image, output_video, output_gallery])
|
||||
run_test_controlnets_btn.click(fn=test_controlnets, inputs=[prompt, negative, input_image], outputs=[preview_process, output_image, output_video, output_gallery])
|
||||
run_test_xs_btn.click(fn=test_xs, inputs=[prompt, negative, input_image], outputs=[preview_process, output_image, output_video, output_gallery])
|
||||
run_test_adapters_btn.click(fn=test_adapters, inputs=[prompt, negative, input_image], outputs=[preview_process, output_image, output_video, output_gallery])
|
||||
run_test_lite_btn.click(fn=test_lite, inputs=[prompt, negative, input_image], outputs=[preview_process, output_image, output_video, output_gallery])
|
||||
run_test_processors_btn.click(fn=test_processors, inputs=[input_image], outputs=[output_image, output_video, output_gallery])
|
||||
run_test_controlnets_btn.click(fn=test_controlnets, inputs=[prompt, negative, input_image], outputs=[output_image, output_video, output_gallery])
|
||||
run_test_xs_btn.click(fn=test_xs, inputs=[prompt, negative, input_image], outputs=[output_image, output_video, output_gallery])
|
||||
run_test_adapters_btn.click(fn=test_adapters, inputs=[prompt, negative, input_image], outputs=[output_image, output_video, output_gallery])
|
||||
run_test_lite_btn.click(fn=test_lite, inputs=[prompt, negative, input_image], outputs=[output_image, output_video, output_gallery])
|
||||
|
||||
ui_extra_networks.setup_ui(extra_networks_ui, output_gallery)
|
||||
return [(control_ui, 'Control', 'control')]
|
||||
|
||||
@@ -11,7 +11,7 @@ from modules import shared, ui_components, ui_symbols, ui_common, masking # pyli
|
||||
from modules import ui_control_helpers as helpers
|
||||
|
||||
|
||||
def create_ui_elements(units, result_txt, preview_process):
|
||||
def create_ui_elements(units, result_txt, output_gallery):
|
||||
max_units = shared.opts.control_max_units
|
||||
with gr.Accordion('Control elements', open=False, elem_id="control_elements"):
|
||||
with gr.Tabs(elem_id='control-tabs') as _tabs_control_type:
|
||||
@@ -54,7 +54,7 @@ def create_ui_elements(units, result_txt, preview_process):
|
||||
process_id = process_id,
|
||||
model_id = model_id,
|
||||
model_strength = model_strength,
|
||||
preview_process = preview_process,
|
||||
preview_process = output_gallery,
|
||||
preview_btn = preview_btn,
|
||||
image_upload = image_upload,
|
||||
image_reuse = image_reuse,
|
||||
@@ -103,7 +103,7 @@ def create_ui_elements(units, result_txt, preview_process):
|
||||
process_id = process_id,
|
||||
model_id = model_id,
|
||||
model_strength = model_strength,
|
||||
preview_process = preview_process,
|
||||
preview_process = output_gallery,
|
||||
preview_btn = btn_preview,
|
||||
image_upload = image_upload,
|
||||
image_reuse = image_reuse,
|
||||
@@ -150,7 +150,7 @@ def create_ui_elements(units, result_txt, preview_process):
|
||||
process_id = process_id,
|
||||
model_id = model_id,
|
||||
model_strength = model_strength,
|
||||
preview_process = preview_process,
|
||||
preview_process = output_gallery,
|
||||
preview_btn = btn_preview,
|
||||
image_upload = image_upload,
|
||||
image_reuse = image_reuse,
|
||||
@@ -196,7 +196,7 @@ def create_ui_elements(units, result_txt, preview_process):
|
||||
process_id = process_id,
|
||||
model_id = model_id,
|
||||
model_strength = model_strength,
|
||||
preview_process = preview_process,
|
||||
preview_process = output_gallery,
|
||||
preview_btn = btn_preview,
|
||||
image_upload = image_upload,
|
||||
image_reuse = image_reuse,
|
||||
@@ -239,7 +239,7 @@ def create_ui_elements(units, result_txt, preview_process):
|
||||
process_id = process_id,
|
||||
model_id = model_id,
|
||||
model_strength = model_strength,
|
||||
preview_process = preview_process,
|
||||
preview_process = output_gallery,
|
||||
preview_btn = btn_preview,
|
||||
image_upload = image_upload,
|
||||
image_reuse = image_reuse,
|
||||
|
||||
@@ -146,17 +146,17 @@ def select_input(input_mode, input_image, init_image, init_type, input_video, in
|
||||
if selected_input is None:
|
||||
# log.debug(f'Select input: image={selected_input}')
|
||||
input_source = None
|
||||
return [gr.Tabs.update(), None, ''] + size
|
||||
return [gr.Tabs.update(), ''] + size
|
||||
elif selected_input == input_prev:
|
||||
# log.debug(f'Select input: image={selected_input} no change')
|
||||
return [gr.Tabs.update(), None, ''] + size
|
||||
return [gr.Tabs.update(), ''] + size
|
||||
input_prev = selected_input
|
||||
|
||||
busy = True
|
||||
input_type = type(selected_input)
|
||||
input_mask = None
|
||||
status = 'Control input | Unknown'
|
||||
res = [gr.Tabs.update(selected='out-gallery'), input_mask, status]
|
||||
res = [gr.Tabs.update(selected='out-gallery'), status]
|
||||
# control inputs
|
||||
if isinstance(selected_input, Image.Image): # image via upload -> image
|
||||
if input_mode == 'Outpaint':
|
||||
@@ -166,7 +166,7 @@ def select_input(input_mode, input_image, init_image, init_type, input_video, in
|
||||
input_type = 'PIL.Image'
|
||||
status = f'Control input | Image | Size {selected_input.width if selected_input else 0}x{selected_input.height if selected_input else 0} | Mode {selected_input.mode if selected_input else "Unknown"}'
|
||||
size = [gr.update(value=selected_input.width), gr.update(value=selected_input.height)]
|
||||
res = [gr.Tabs.update(selected='out-gallery'), input_mask, status]
|
||||
res = [gr.Tabs.update(selected='out-gallery'), status]
|
||||
elif isinstance(selected_input, dict) and 'kanvas' in selected_input: # kanvas via js -> kanvas dict
|
||||
selected_input, input_mask = process_kanvas(selected_input)
|
||||
input_source = [selected_input]
|
||||
@@ -174,23 +174,23 @@ def select_input(input_mode, input_image, init_image, init_type, input_video, in
|
||||
status = f'Control input | Kanvas | Size {selected_input.width if selected_input else 0}x{selected_input.height if selected_input else 0} | Mode {selected_input.mode if selected_input else "Unknown"}'
|
||||
if selected_input:
|
||||
size = [gr.update(value=selected_input.width), gr.update(value=selected_input.height)]
|
||||
res = [gr.Tabs.update(selected='out-gallery'), input_mask, status]
|
||||
res = [gr.Tabs.update(selected='out-gallery'), status]
|
||||
elif isinstance(selected_input, dict) and 'mask' in selected_input: # inpaint -> dict image+mask
|
||||
input_mask = selected_input['mask']
|
||||
selected_input = selected_input['image']
|
||||
input_source = [selected_input]
|
||||
input_type = 'PIL.Image'
|
||||
status = f'Control input | Image | Size {selected_input.width if selected_input else 0}x{selected_input.height if selected_input else 0} | Mode {selected_input.mode if selected_input else "Unknown"}'
|
||||
res = [gr.Tabs.update(selected='out-gallery'), input_mask, status]
|
||||
res = [gr.Tabs.update(selected='out-gallery'), status]
|
||||
elif isinstance(selected_input, gr.components.image.Image): # not likely
|
||||
input_source = [selected_input.value]
|
||||
input_type = 'gr.Image'
|
||||
res = [gr.Tabs.update(selected='out-gallery'), input_mask, status]
|
||||
res = [gr.Tabs.update(selected='out-gallery'), status]
|
||||
elif isinstance(selected_input, str) and os.path.exists(selected_input): # video via upload > tmp filepath to video
|
||||
input_source = selected_input
|
||||
input_type = 'gr.Video'
|
||||
status = get_video(input_source)
|
||||
res = [gr.Tabs.update(selected='out-video'), input_mask, status]
|
||||
res = [gr.Tabs.update(selected='out-video'), status]
|
||||
elif isinstance(selected_input, list): # batch or folder via upload -> list of tmp filepaths
|
||||
if hasattr(selected_input[0], 'name'):
|
||||
input_type = 'tempfiles'
|
||||
@@ -199,7 +199,7 @@ def select_input(input_mode, input_image, init_image, init_type, input_video, in
|
||||
input_type = 'files'
|
||||
input_source = selected_input
|
||||
status = f'Control input | Images | Files {len(input_source)}'
|
||||
res = [gr.Tabs.update(selected='out-gallery'), input_mask, status]
|
||||
res = [gr.Tabs.update(selected='out-gallery'), status]
|
||||
else: # unknown
|
||||
input_source = None
|
||||
if init_type == 0: # Control only
|
||||
|
||||
+1
-1
Submodule wiki updated: 0702187356...890415e996
Reference in New Issue
Block a user