Merge pull request #9108 from AUTOMATIC1111/img2img-scale-by
add "resize by" and "resize to" tabs to img2img
This commit is contained in:
commit
b615a2ed11
@ -361,3 +361,8 @@ function selectCheckpoint(name){
|
|||||||
desiredCheckpointName = name;
|
desiredCheckpointName = name;
|
||||||
gradioApp().getElementById('change_checkpoint').click()
|
gradioApp().getElementById('change_checkpoint').click()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function currentImg2imgSourceResolution(_, _, scaleBy){
|
||||||
|
var img = gradioApp().querySelector('#mode_img2img > div[style="display: block;"] img')
|
||||||
|
return img ? [img.naturalWidth, img.naturalHeight, scaleBy] : [0, 0, scaleBy]
|
||||||
|
}
|
||||||
|
@ -81,7 +81,7 @@ def process_batch(p, input_dir, output_dir, inpaint_mask_dir, args):
|
|||||||
processed_image.save(os.path.join(output_dir, filename))
|
processed_image.save(os.path.join(output_dir, filename))
|
||||||
|
|
||||||
|
|
||||||
def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_styles, init_img, sketch, init_img_with_mask, inpaint_color_sketch, inpaint_color_sketch_orig, init_img_inpaint, init_mask_inpaint, steps: int, sampler_index: int, mask_blur: int, mask_alpha: float, inpainting_fill: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, image_cfg_scale: float, denoising_strength: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, height: int, width: int, resize_mode: int, inpaint_full_res: bool, inpaint_full_res_padding: int, inpainting_mask_invert: int, img2img_batch_input_dir: str, img2img_batch_output_dir: str, img2img_batch_inpaint_mask_dir: str, override_settings_texts, *args):
|
def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_styles, init_img, sketch, init_img_with_mask, inpaint_color_sketch, inpaint_color_sketch_orig, init_img_inpaint, init_mask_inpaint, steps: int, sampler_index: int, mask_blur: int, mask_alpha: float, inpainting_fill: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, image_cfg_scale: float, denoising_strength: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, selected_scale_tab: int, height: int, width: int, scale_by: float, resize_mode: int, inpaint_full_res: bool, inpaint_full_res_padding: int, inpainting_mask_invert: int, img2img_batch_input_dir: str, img2img_batch_output_dir: str, img2img_batch_inpaint_mask_dir: str, override_settings_texts, *args):
|
||||||
override_settings = create_override_settings_dict(override_settings_texts)
|
override_settings = create_override_settings_dict(override_settings_texts)
|
||||||
|
|
||||||
is_batch = mode == 5
|
is_batch = mode == 5
|
||||||
@ -117,6 +117,12 @@ def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_s
|
|||||||
if image is not None:
|
if image is not None:
|
||||||
image = ImageOps.exif_transpose(image)
|
image = ImageOps.exif_transpose(image)
|
||||||
|
|
||||||
|
if selected_scale_tab == 1:
|
||||||
|
assert image, "Can't scale by because no image is selected"
|
||||||
|
|
||||||
|
width = int(image.width * scale_by)
|
||||||
|
height = int(image.height * scale_by)
|
||||||
|
|
||||||
assert 0. <= denoising_strength <= 1., 'can only work with strength in [0.0, 1.0]'
|
assert 0. <= denoising_strength <= 1., 'can only work with strength in [0.0, 1.0]'
|
||||||
|
|
||||||
p = StableDiffusionProcessingImg2Img(
|
p = StableDiffusionProcessingImg2Img(
|
||||||
|
@ -130,6 +130,16 @@ def calc_resolution_hires(enable, width, height, hr_scale, hr_resize_x, hr_resiz
|
|||||||
return f"resize: from <span class='resolution'>{p.width}x{p.height}</span> to <span class='resolution'>{p.hr_resize_x or p.hr_upscale_to_x}x{p.hr_resize_y or p.hr_upscale_to_y}</span>"
|
return f"resize: from <span class='resolution'>{p.width}x{p.height}</span> to <span class='resolution'>{p.hr_resize_x or p.hr_upscale_to_x}x{p.hr_resize_y or p.hr_upscale_to_y}</span>"
|
||||||
|
|
||||||
|
|
||||||
|
def resize_from_to_html(width, height, scale_by):
|
||||||
|
target_width = int(width * scale_by)
|
||||||
|
target_height = int(height * scale_by)
|
||||||
|
|
||||||
|
if not target_width or not target_height:
|
||||||
|
return "no image selected"
|
||||||
|
|
||||||
|
return f"resize: from <span class='resolution'>{width}x{height}</span> to <span class='resolution'>{target_width}x{target_height}</span>"
|
||||||
|
|
||||||
|
|
||||||
def apply_styles(prompt, prompt_neg, styles):
|
def apply_styles(prompt, prompt_neg, styles):
|
||||||
prompt = shared.prompt_styles.apply_styles_to_prompt(prompt, styles)
|
prompt = shared.prompt_styles.apply_styles_to_prompt(prompt, styles)
|
||||||
prompt_neg = shared.prompt_styles.apply_negative_styles_to_prompt(prompt_neg, styles)
|
prompt_neg = shared.prompt_styles.apply_negative_styles_to_prompt(prompt_neg, styles)
|
||||||
@ -676,6 +686,8 @@ def create_ui():
|
|||||||
copy_image_buttons.append((button, name, elem))
|
copy_image_buttons.append((button, name, elem))
|
||||||
|
|
||||||
with gr.Tabs(elem_id="mode_img2img"):
|
with gr.Tabs(elem_id="mode_img2img"):
|
||||||
|
img2img_selected_tab = gr.State(0)
|
||||||
|
|
||||||
with gr.TabItem('img2img', id='img2img', elem_id="img2img_img2img_tab") as tab_img2img:
|
with gr.TabItem('img2img', id='img2img', elem_id="img2img_img2img_tab") as tab_img2img:
|
||||||
init_img = gr.Image(label="Image for img2img", elem_id="img2img_image", show_label=False, source="upload", interactive=True, type="pil", tool="editor", image_mode="RGBA").style(height=480)
|
init_img = gr.Image(label="Image for img2img", elem_id="img2img_image", show_label=False, source="upload", interactive=True, type="pil", tool="editor", image_mode="RGBA").style(height=480)
|
||||||
add_copy_image_controls('img2img', init_img)
|
add_copy_image_controls('img2img', init_img)
|
||||||
@ -718,6 +730,12 @@ def create_ui():
|
|||||||
img2img_batch_output_dir = gr.Textbox(label="Output directory", **shared.hide_dirs, elem_id="img2img_batch_output_dir")
|
img2img_batch_output_dir = gr.Textbox(label="Output directory", **shared.hide_dirs, elem_id="img2img_batch_output_dir")
|
||||||
img2img_batch_inpaint_mask_dir = gr.Textbox(label="Inpaint batch mask directory (required for inpaint batch processing only)", **shared.hide_dirs, elem_id="img2img_batch_inpaint_mask_dir")
|
img2img_batch_inpaint_mask_dir = gr.Textbox(label="Inpaint batch mask directory (required for inpaint batch processing only)", **shared.hide_dirs, elem_id="img2img_batch_inpaint_mask_dir")
|
||||||
|
|
||||||
|
img2img_tabs = [tab_img2img, tab_sketch, tab_inpaint, tab_inpaint_color, tab_inpaint_upload, tab_batch]
|
||||||
|
img2img_image_inputs = [init_img, sketch, init_img_with_mask, inpaint_color_sketch]
|
||||||
|
|
||||||
|
for i, tab in enumerate(img2img_tabs):
|
||||||
|
tab.select(fn=lambda tabnum=i: tabnum, inputs=[], outputs=[img2img_selected_tab])
|
||||||
|
|
||||||
def copy_image(img):
|
def copy_image(img):
|
||||||
if isinstance(img, dict) and 'image' in img:
|
if isinstance(img, dict) and 'image' in img:
|
||||||
return img['image']
|
return img['image']
|
||||||
@ -745,14 +763,37 @@ def create_ui():
|
|||||||
steps, sampler_index = create_sampler_and_steps_selection(samplers_for_img2img, "img2img")
|
steps, sampler_index = create_sampler_and_steps_selection(samplers_for_img2img, "img2img")
|
||||||
|
|
||||||
elif category == "dimensions":
|
elif category == "dimensions":
|
||||||
|
with FormRow():
|
||||||
|
with gr.Column(elem_id="img2img_column_size", scale=4):
|
||||||
|
selected_scale_tab = gr.State(value=0)
|
||||||
|
|
||||||
|
with gr.Tabs():
|
||||||
|
with gr.Tab(label="Resize to") as tab_scale_to:
|
||||||
with FormRow():
|
with FormRow():
|
||||||
with gr.Column(elem_id="img2img_column_size", scale=4):
|
with gr.Column(elem_id="img2img_column_size", scale=4):
|
||||||
width = gr.Slider(minimum=64, maximum=2048, step=8, label="Width", value=512, elem_id="img2img_width")
|
width = gr.Slider(minimum=64, maximum=2048, step=8, label="Width", value=512, elem_id="img2img_width")
|
||||||
height = gr.Slider(minimum=64, maximum=2048, step=8, label="Height", value=512, elem_id="img2img_height")
|
height = gr.Slider(minimum=64, maximum=2048, step=8, label="Height", value=512, elem_id="img2img_height")
|
||||||
|
|
||||||
with gr.Column(elem_id="img2img_dimensions_row", scale=1, elem_classes="dimensions-tools"):
|
with gr.Column(elem_id="img2img_dimensions_row", scale=1, elem_classes="dimensions-tools"):
|
||||||
res_switch_btn = ToolButton(value=switch_values_symbol, elem_id="img2img_res_switch_btn")
|
res_switch_btn = ToolButton(value=switch_values_symbol, elem_id="img2img_res_switch_btn")
|
||||||
|
|
||||||
|
with gr.Tab(label="Resize by") as tab_scale_by:
|
||||||
|
scale_by = gr.Slider(minimum=0.05, maximum=4.0, step=0.05, label="Scale", value=1.0, elem_id="img2img_scale")
|
||||||
|
|
||||||
|
with FormRow():
|
||||||
|
scale_by_html = FormHTML(resize_from_to_html(0, 0, 0.0), elem_id="img2img_scale_resolution_preview")
|
||||||
|
gr.Slider(label="Unused", elem_id="img2img_unused_scale_by_slider")
|
||||||
|
|
||||||
|
scale_by.change(
|
||||||
|
fn=resize_from_to_html,
|
||||||
|
_js="currentImg2imgSourceResolution",
|
||||||
|
inputs=[dummy_component, dummy_component, scale_by],
|
||||||
|
outputs=scale_by_html,
|
||||||
|
show_progress=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
tab_scale_to.select(fn=lambda: 0, inputs=[], outputs=[selected_scale_tab])
|
||||||
|
tab_scale_by.select(fn=lambda: 1, inputs=[], outputs=[selected_scale_tab])
|
||||||
|
|
||||||
if opts.dimensions_and_batch_together:
|
if opts.dimensions_and_batch_together:
|
||||||
with gr.Column(elem_id="img2img_column_batch"):
|
with gr.Column(elem_id="img2img_column_batch"):
|
||||||
batch_count = gr.Slider(minimum=1, step=1, label='Batch count', value=1, elem_id="img2img_batch_count")
|
batch_count = gr.Slider(minimum=1, step=1, label='Batch count', value=1, elem_id="img2img_batch_count")
|
||||||
@ -809,7 +850,7 @@ def create_ui():
|
|||||||
def select_img2img_tab(tab):
|
def select_img2img_tab(tab):
|
||||||
return gr.update(visible=tab in [2, 3, 4]), gr.update(visible=tab == 3),
|
return gr.update(visible=tab in [2, 3, 4]), gr.update(visible=tab == 3),
|
||||||
|
|
||||||
for i, elem in enumerate([tab_img2img, tab_sketch, tab_inpaint, tab_inpaint_color, tab_inpaint_upload, tab_batch]):
|
for i, elem in enumerate(img2img_tabs):
|
||||||
elem.select(
|
elem.select(
|
||||||
fn=lambda tab=i: select_img2img_tab(tab),
|
fn=lambda tab=i: select_img2img_tab(tab),
|
||||||
inputs=[],
|
inputs=[],
|
||||||
@ -862,8 +903,10 @@ def create_ui():
|
|||||||
denoising_strength,
|
denoising_strength,
|
||||||
seed,
|
seed,
|
||||||
subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w, seed_checkbox,
|
subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w, seed_checkbox,
|
||||||
|
selected_scale_tab,
|
||||||
height,
|
height,
|
||||||
width,
|
width,
|
||||||
|
scale_by,
|
||||||
resize_mode,
|
resize_mode,
|
||||||
inpaint_full_res,
|
inpaint_full_res,
|
||||||
inpaint_full_res_padding,
|
inpaint_full_res_padding,
|
||||||
|
19
style.css
19
style.css
@ -293,7 +293,12 @@ button.custom-button{
|
|||||||
margin-left: -0.75em
|
margin-left: -0.75em
|
||||||
}
|
}
|
||||||
|
|
||||||
#txtimg_hr_finalres .resolution{
|
#img2img_scale_resolution_preview.block{
|
||||||
|
display: flex;
|
||||||
|
align-items: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
#txtimg_hr_finalres .resolution, #img2img_scale_resolution_preview .resolution{
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -337,6 +342,18 @@ div#extras_scale_to_tab div.form{
|
|||||||
overflow-wrap: break-word;
|
overflow-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#img2img_column_batch{
|
||||||
|
align-self: end;
|
||||||
|
margin-bottom: 0.9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#img2img_unused_scale_by_slider{
|
||||||
|
visibility: hidden;
|
||||||
|
width: 0.5em;
|
||||||
|
max-width: 0.5em;
|
||||||
|
min-width: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
/* settings */
|
/* settings */
|
||||||
#quicksettings {
|
#quicksettings {
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
|
Loading…
Reference in New Issue
Block a user