mirror of https://github.com/vladmandic/automatic
controlnet allow processor to keep aspect-ratio for override images based on i2i or t2i resolution
Signed-off-by: Vladimir Mandic <mandic00@live.com>pull/4359/head
parent
4a48695918
commit
9927b3e62c
|
|
@ -20,6 +20,7 @@
|
|||
- add setting to control `cudnn` enable/disable
|
||||
- change `vlm` beams to 1 by default for faster response
|
||||
- update diffusers
|
||||
- **controlnet** allow processor to keep aspect-ratio for override images based on i2i or t2i resolution
|
||||
- **Fixes**
|
||||
- `qwen` improve lora compatibility
|
||||
- `chrono` transformers handling
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 9f0e3f3360f5927d05ca8a2e728c80fbbda4c941
|
||||
Subproject commit 388c2234378fb0c45575d4e7993470377abfa790
|
||||
|
|
@ -2208,6 +2208,18 @@ div:has(>#tab-gallery-folders) {
|
|||
font-weight: normal;
|
||||
}
|
||||
|
||||
.controlnet-controls .styler {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-self: flex-start;
|
||||
}
|
||||
|
||||
.controlnet-controls .styler .form {
|
||||
display: flex;
|
||||
flex-flow: nowrap;
|
||||
flex: none;
|
||||
}
|
||||
|
||||
#civitai_token textarea, #hf_token textarea, #setting_huggingface_token textarea {
|
||||
filter: blur(4px);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,8 +55,8 @@ def preprocess_image(
|
|||
jobid = shared.state.begin('Preprocess')
|
||||
|
||||
# run resize before
|
||||
if p.resize_mode_before != 0 and p.resize_name_before != 'None':
|
||||
if p.selected_scale_tab_before == 1 and input_image is not None:
|
||||
if (p.resize_mode_before != 0) and (p.resize_name_before != 'None'):
|
||||
if (p.selected_scale_tab_before == 1) and (input_image is not None):
|
||||
p.width_before, p.height_before = int(input_image.width * p.scale_by_before), int(input_image.height * p.scale_by_before)
|
||||
if input_image is not None:
|
||||
debug_log(f'Control resize: op=before image={input_image} width={p.width_before} height={p.height_before} mode={p.resize_mode_before} name={p.resize_name_before} context="{p.resize_context_before}"')
|
||||
|
|
@ -64,10 +64,10 @@ def preprocess_image(
|
|||
p.init_img_width = getattr(p, 'init_img_width', input_image.width) # pylint: disable=attribute-defined-outside-init
|
||||
p.init_img_height = getattr(p, 'init_img_height', input_image.height) # pylint: disable=attribute-defined-outside-init
|
||||
input_image = images.resize_image(p.resize_mode_before, input_image, p.width_before, p.height_before, p.resize_name_before, context=p.resize_context_before)
|
||||
if input_image is not None and init_image is not None and init_image.size != input_image.size:
|
||||
if (input_image is not None) and (init_image is not None) and (init_image.size != input_image.size):
|
||||
debug_log(f'Control resize init: image={init_image} target={input_image}')
|
||||
init_image = images.resize_image(resize_mode=1, im=init_image, width=input_image.width, height=input_image.height)
|
||||
if input_image is not None and p.override is not None and p.override.size != input_image.size:
|
||||
if (input_image is not None) and (p.override is not None) and (p.override.size != input_image.size):
|
||||
debug_log(f'Control resize override: image={p.override} target={input_image}')
|
||||
p.override = images.resize_image(resize_mode=1, im=p.override, width=input_image.width, height=input_image.height)
|
||||
if input_image is not None:
|
||||
|
|
@ -100,10 +100,16 @@ def preprocess_image(
|
|||
blended_image = None
|
||||
for i, process in enumerate(active_process): # list[image]
|
||||
debug_log(f'Control: i={i+1} process="{process.processor_id}" input={masked_image} override={process.override}')
|
||||
if p.resize_mode_before != 0:
|
||||
resize_mode = p.resize_mode_before
|
||||
else:
|
||||
resize_mode = 3 if shared.opts.control_aspect_ratio else 1
|
||||
processed_image = process(
|
||||
image_input=masked_image,
|
||||
width=p.width,
|
||||
height=p.height,
|
||||
mode='RGB',
|
||||
resize_mode=p.resize_mode_before,
|
||||
resize_mode=resize_mode,
|
||||
resize_name=p.resize_name_before,
|
||||
scale_tab=p.selected_scale_tab_before,
|
||||
scale_by=p.scale_by_before,
|
||||
|
|
|
|||
|
|
@ -268,12 +268,14 @@ class Processor():
|
|||
display(e, 'Control Processor load')
|
||||
return f'Processor load filed: {processor_id}'
|
||||
|
||||
def __call__(self, image_input: Image, mode: str = 'RGB', resize_mode: int = 0, resize_name: str = 'None', scale_tab: int = 1, scale_by: float = 1.0, local_config: dict = {}):
|
||||
def __call__(self, image_input: Image, mode: str = 'RGB', width: int = 0, height: int = 0, resize_mode: int = 0, resize_name: str = 'None', scale_tab: int = 1, scale_by: float = 1.0, local_config: dict = {}):
|
||||
if self.override is not None:
|
||||
debug(f'Control Processor: id="{self.processor_id}" override={self.override}')
|
||||
if image_input is not None and image_input.size != self.override.size:
|
||||
debug(f'Control resize: op=override image={self.override} width={image_input.width} height={image_input.height} mode={resize_mode} name={resize_name}')
|
||||
image_input = images.resize_image(resize_mode, self.override, image_input.width, image_input.height, resize_name)
|
||||
width = image_input.width if image_input is not None else width
|
||||
height = image_input.height if image_input is not None else height
|
||||
if (width != self.override.width) or (height != self.override.height):
|
||||
debug(f'Control resize: op=override image={self.override} width={width} height={height} mode={resize_mode} name={resize_name}')
|
||||
image_input = images.resize_image(resize_mode, self.override, width, height, resize_name)
|
||||
else:
|
||||
image_input = self.override
|
||||
if resize_mode != 0 and resize_name != 'None':
|
||||
|
|
|
|||
|
|
@ -356,7 +356,7 @@ class ControlNet():
|
|||
self.model.to_empty(device=self.device) # model could be sparse
|
||||
if "Control" in opts.sdnq_quantize_weights:
|
||||
try:
|
||||
log.debug(f'Control {what} model SDNQ Compress: id="{model_id}"')
|
||||
log.debug(f'Control {what} model SDNQ quantize: id="{model_id}"')
|
||||
from modules.model_quant import sdnq_quantize_model
|
||||
self.model = sdnq_quantize_model(self.model)
|
||||
except Exception as e:
|
||||
|
|
|
|||
|
|
@ -745,7 +745,8 @@ options_templates.update(options_section(('hidden_options', "Hidden options"), {
|
|||
"tooltips": OptionInfo("UI Tooltips", "UI tooltips", gr.Radio, {"choices": ["None", "Browser default", "UI tooltips"], "visible": False}),
|
||||
|
||||
# control settings are handled separately
|
||||
"control_hires": OptionInfo(False, "Use control during hires", gr.Checkbox, {"visible": False}),
|
||||
"control_hires": OptionInfo(False, "Hires use Control", gr.Checkbox, {"visible": False}),
|
||||
"control_aspect_ratio": OptionInfo(False, "Aspect ratio resize", gr.Checkbox, {"visible": False}),
|
||||
"control_max_units": OptionInfo(4, "Maximum number of units", gr.Slider, {"minimum": 1, "maximum": 10, "step": 1, "visible": False}),
|
||||
"control_tiles": OptionInfo("1x1, 1x2, 1x3, 1x4, 2x1, 2x1, 2x2, 2x3, 2x4, 3x1, 3x2, 3x3, 3x4, 4x1, 4x2, 4x3, 4x4", "Tiling options", gr.Textbox, {"visible": False}),
|
||||
"control_move_processor": OptionInfo(False, "Processor move to CPU after use", gr.Checkbox, {"visible": False}),
|
||||
|
|
|
|||
|
|
@ -28,7 +28,12 @@ def create_ui_elements(units, result_txt, preview_process):
|
|||
enabled = True if i==0 else False
|
||||
with gr.Accordion(f'ControlNet unit {i+1}', visible= i < num_controlnet_units.value, elem_classes='control-unit') as unit_ui:
|
||||
with gr.Row():
|
||||
enabled_cb = gr.Checkbox(enabled, label='Active', container=False, show_label=True, elem_id=f'control_unit-{i}-enabled')
|
||||
with gr.Group(elem_id=f'controlnet_unit-{i}-controls', elem_classes='controlnet-controls'):
|
||||
enabled_cb = gr.Checkbox(enabled, label='Active', container=False, show_label=True, elem_id=f'control_unit-{i}-enabled')
|
||||
image_upload = gr.UploadButton(label=ui_symbols.upload, file_types=['image'], elem_classes=['form', 'gradio-button', 'tool'], elem_id=f'controlnet_unit-{i}-upload')
|
||||
image_reuse= ui_components.ToolButton(value=ui_symbols.reuse, elem_id=f'controlnet_unit-{i}-reuse')
|
||||
reset_btn = ui_components.ToolButton(value=ui_symbols.reset, elem_id=f'controlnet_unit-{i}-reset')
|
||||
preview_btn = ui_components.ToolButton(value=ui_symbols.preview, elem_id=f'controlnet_unit-{i}-preview')
|
||||
process_id = gr.Dropdown(label="Processor", choices=processors.list_models(), value='None', elem_id=f'control_unit-{i}-process_name')
|
||||
model_id = gr.Dropdown(label="ControlNet", choices=controlnet.list_models(), value='None', elem_id=f'control_unit-{i}-model_name')
|
||||
ui_common.create_refresh_button(model_id, controlnet.list_models, lambda: {"choices": controlnet.list_models(refresh=True)}, f'controlnet_models_{i}_refresh')
|
||||
|
|
@ -37,10 +42,6 @@ def create_ui_elements(units, result_txt, preview_process):
|
|||
control_start = gr.Slider(label="CN Start", minimum=0.0, maximum=1.0, step=0.05, value=0, elem_id=f'control_unit-{i}-start')
|
||||
control_end = gr.Slider(label="CN End", minimum=0.0, maximum=1.0, step=0.05, value=1.0, elem_id=f'control_unit-{i}-end')
|
||||
control_tile = gr.Dropdown(label="CN Tiles", choices=[x.strip() for x in shared.opts.control_tiles.split(',') if 'x' in x], value='1x1', visible=False, elem_id=f'control_unit-{i}-tile')
|
||||
reset_btn = ui_components.ToolButton(value=ui_symbols.reset, elem_id=f'controlnet_unit-{i}-reset')
|
||||
image_upload = gr.UploadButton(label=ui_symbols.upload, file_types=['image'], elem_classes=['form', 'gradio-button', 'tool'], elem_id=f'controlnet_unit-{i}-upload')
|
||||
image_reuse= ui_components.ToolButton(value=ui_symbols.reuse, elem_id=f'controlnet_unit-{i}-reuse')
|
||||
btn_preview= ui_components.ToolButton(value=ui_symbols.preview, elem_id=f'controlnet_unit-{i}-preview')
|
||||
image_preview = gr.Image(label="Input", type="pil", height=128, width=128, visible=False, interactive=True, show_label=False, show_download_button=False, container=False, elem_id=f'controlnet_unit-{i}-override')
|
||||
controlnet_ui_units.append(unit_ui)
|
||||
units.append(unit.Unit(
|
||||
|
|
@ -54,7 +55,7 @@ def create_ui_elements(units, result_txt, preview_process):
|
|||
model_id = model_id,
|
||||
model_strength = model_strength,
|
||||
preview_process = preview_process,
|
||||
preview_btn = btn_preview,
|
||||
preview_btn = preview_btn,
|
||||
image_upload = image_upload,
|
||||
image_reuse = image_reuse,
|
||||
image_preview = image_preview,
|
||||
|
|
@ -253,10 +254,6 @@ def create_ui_elements(units, result_txt, preview_process):
|
|||
with gr.Group(elem_classes=['processor-group']):
|
||||
settings = []
|
||||
with gr.Accordion('Global', open=True, elem_classes=['processor-settings']):
|
||||
control_hires = gr.Checkbox(label="Use control during hires", value=shared.opts.control_hires, elem_id='control_hires')
|
||||
def set_control_hires(value):
|
||||
shared.opts.control_hires = value
|
||||
control_hires.change(fn=set_control_hires, inputs=[control_hires], outputs=[])
|
||||
control_max_units = gr.Slider(label="Maximum units", minimum=1, maximum=10, step=1, value=shared.opts.control_max_units, elem_id='control_max_units')
|
||||
def set_control_max_units(value):
|
||||
shared.opts.control_max_units = value
|
||||
|
|
@ -265,11 +262,19 @@ def create_ui_elements(units, result_txt, preview_process):
|
|||
def set_control_tiles(value):
|
||||
shared.opts.control_tiles = value
|
||||
control_tiles.change(fn=set_control_tiles, inputs=[control_tiles], outputs=[])
|
||||
control_move_processor = gr.Checkbox(label="Move processor to CPU after use", value=shared.opts.control_move_processor, elem_id='control_move_processor')
|
||||
control_hires = gr.Checkbox(label="Hires use control", value=shared.opts.control_hires, elem_id='control_hires')
|
||||
def set_control_hires(value):
|
||||
shared.opts.control_hires = value
|
||||
control_hires.change(fn=set_control_hires, inputs=[control_hires], outputs=[])
|
||||
control_aspect_ratio = gr.Checkbox(label="Keep aspect ratio", value=shared.opts.control_aspect_ratio, elem_id='control_aspect_ratio')
|
||||
def set_control_aspect_ratio(value):
|
||||
shared.opts.control_aspect_ratio = value
|
||||
control_aspect_ratio.change(fn=set_control_aspect_ratio, inputs=[control_aspect_ratio], outputs=[])
|
||||
control_move_processor = gr.Checkbox(label="Offload processor", value=shared.opts.control_move_processor, elem_id='control_move_processor')
|
||||
def set_control_move_processor(value):
|
||||
shared.opts.control_move_processor = value
|
||||
control_move_processor.change(fn=set_control_move_processor, inputs=[control_move_processor], outputs=[])
|
||||
control_unload_processor = gr.Checkbox(label="Unload processor after use", value=shared.opts.control_unload_processor, elem_id='control_unload_processor')
|
||||
control_unload_processor = gr.Checkbox(label="Unload processor", value=shared.opts.control_unload_processor, elem_id='control_unload_processor')
|
||||
def set_control_unload_processor(value):
|
||||
shared.opts.control_unload_processor = value
|
||||
control_unload_processor.change(fn=set_control_unload_processor, inputs=[control_unload_processor], outputs=[])
|
||||
|
|
|
|||
Loading…
Reference in New Issue