configurable image fit in all image views

Signed-off-by: Vladimir Mandic <mandic00@live.com>
pull/4115/head
Vladimir Mandic 2025-08-06 11:33:50 -04:00
parent 7bba30e797
commit 6a6605191f
8 changed files with 43 additions and 8 deletions

View File

@ -38,12 +38,13 @@ And (*as always*) many bugfixes and improvements to existing features!
- updated real-time hints, thanks @CalamitousFelicitousness
- rewritten **CivitAI downloader**
in *models -> civitai*
- quicksettings reset button to restore all quicksettings to default values
because things do sometimes get wrong...
- configurable image fit in all image views
- updated *models -> current* tab
- updated *models -> list models* tab
- updated *models -> metadata* tab
- updated *extensions* tab
- quicksettings reset button to restore all quicksettings to default values
because things do sometimes get wrong...
- redesign *settings -> user interface*
- gallery bypass browser cache for thumbnails
- gallery safer delete operation

View File

@ -19,6 +19,7 @@
{"id":"","label":"🖌️","localized":"","hint":"LaMa remove selected object from image"},
{"id":"","label":"🖼️","localized":"","hint":"Show preview"},
{"id":"","label":"♻","localized":"","hint":"Interrogate image"},
{"id":"","label":"⁜","localized":"","hint":"Cycle image fit method"},
{"id":"","label":"↶","localized":"","hint":"Apply selected style to prompt"},
{"id":"","label":"↷","localized":"","hint":"Save current prompt to style"},
{"id":"","label":"","localized":"","hint":"Sort by name, ascending"},

View File

@ -3,6 +3,18 @@ let previewDrag = false;
let modalPreviewZone;
let previewInstance;
function cycleImageFit() {
const root = document.documentElement;
const current = getComputedStyle(root).getPropertyValue('--sd-image-fit').trim();
let next = 'contain';
if (current === 'contain') next = 'cover';
else if (current === 'cover') next = 'fill';
else if (current === 'fill') next = 'scale-down';
else if (current === 'scale-down') next = 'none';
root.style.setProperty('--sd-image-fit', next);
log('cycleImageFit', current, next);
}
function closeModal(evt, force = false) {
if (force) gradioApp().getElementById('lightboxModal').style.display = 'none';
if (previewDrag) return;

View File

@ -14,6 +14,7 @@
--color-trace: #666666;
--color-warning: #FF9900;
--left-column: 530px;
--sd-image-fit: contain;
}
a {
@ -515,17 +516,36 @@ color: var(--primary-500) !important
color: var(--body-text-color-subdued) !important
}
.gradio-gallery img, .image-container img {
max-width: 100%;
object-position: top;
width: 100%;
height: 100%;
object-fit: var(--sd-image-fit) !important;
}
.interrogate {
background: none !important;
font-size: 1.5em !important;
max-width: fit-content;
position: absolute;
right: 2.8em;
top: 0.2em;
top: 0.1em;
z-index: 50;
}
.interrogate:hover {
.image-fit {
background: none !important;
font-size: 1.5em !important;
max-width: fit-content;
position: absolute;
right: 4.0em;
top: 0.1em;
z-index: 50;
}
.interrogate:hover,
.image-fit:hover {
background: var(--button-primary-background-fill-hover) !important;
}

View File

@ -150,7 +150,7 @@ def create_sdnq_config(kwargs = None, allow: bool = True, module: str = 'Model',
return_device=return_device,
modules_to_not_convert=modules_to_not_convert,
)
log.debug(f'Quantization: module="{module}" type=sdnq dtype={weights_dtype} matmul={shared.opts.sdnq_use_quantized_matmul} group_size={shared.opts.sdnq_quantize_weights_group_size} quant_conv={shared.opts.sdnq_quantize_conv_layers} matmul_conv={shared.opts.sdnq_use_quantized_matmul_conv} dequantize_fp32={shared.opts.sdnq_dequantize_fp32} quantize_with_gpu={shared.opts.sdnq_quantize_with_gpu} quantization_device={quantization_device} return_device={return_device} device_map={shared.opts.device_map} offload_mode={shared.opts.diffusers_offload_mode}')
log.debug(f'Quantization: module="{module}" type=sdnq dtype={weights_dtype} matmul={shared.opts.sdnq_use_quantized_matmul} group_size={shared.opts.sdnq_quantize_weights_group_size} quant_conv={shared.opts.sdnq_quantize_conv_layers} matmul_conv={shared.opts.sdnq_use_quantized_matmul_conv} dequantize_fp32={shared.opts.sdnq_dequantize_fp32} quantize_with_gpu={shared.opts.sdnq_quantize_with_gpu} quantization_device={quantization_device} return_device={return_device} device_map={shared.opts.device_map} offload_mode={shared.opts.diffusers_offload_mode} non_blocking={shared.opts.diffusers_offload_nonblocking}')
if kwargs is None:
return sdnq_config
else:

View File

@ -247,6 +247,8 @@ def create_output_panel(tabname, preview=True, prompt=None, height=None, transfe
)
if prompt is not None:
ui_sections.create_interrogate_button(tab=tabname, inputs=result_gallery, outputs=prompt, what='output')
button_image_fit = gr.Button(ui_symbols.resize, elem_id=f"{tabname}_image_fit", elem_classes=['image-fit'])
button_image_fit.click(fn=None, _js="cycleImageFit", inputs=[], outputs=[])
with gr.Column(elem_id=f"{tabname}_footer", elem_classes="gallery_footer"):
dummy_component = gr.Label(visible=False)

View File

@ -215,7 +215,7 @@ def create_ui(_blocks: gr.Blocks=None):
gr.HTML('<span id="control-output-button">Output</p>')
with gr.Tabs(elem_classes=['control-tabs'], elem_id='control-tab-output') as output_tabs:
with gr.Tab('Gallery', id='out-gallery'):
output_gallery, _output_gen_info, _output_html_info, _output_html_info_formatted, output_html_log = ui_common.create_output_panel("control", preview=True, prompt=prompt, height=gr_height)
output_gallery, _output_gen_info, _output_html_info, _output_html_info_formatted, output_html_log = ui_common.create_output_panel("control", preview=False, prompt=prompt, height=gr_height)
with gr.Tab('Image', id='out-image'):
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'):

View File

@ -25,8 +25,7 @@ reuse = '⬅️'
search = '🔍'
preview = '🖼️'
image = '🖌️'
mark_diag = ''
mark_flag = ''
resize = ''
interrogate = ''
int_clip = ''
int_blip = ''