diff --git a/CHANGELOG.md b/CHANGELOG.md index f97a7a0e8..c6b560f0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ - **LCM** support for any *SD 1.5* or *SD-XL* model! - download [lcm-lora-sd15](https://huggingface.co/latent-consistency/lcm-lora-sdv1-5/tree/main) and/or [lcm-lora-sdxl](https://huggingface.co/latent-consistency/lcm-lora-sdxl/tree/main) - load for favorite *SD 1.5* or *SD-XL* model *(original LCM was SD 1.5 only, this is both)* - - load **lcm lora** + - load **lcm lora** *(note: lcm lora is processed differently than any other lora)* - set **sampler** to **LCM** - set number of steps to some low number, for SD-XL 6-7 steps is normally sufficient note: LCM scheduler does not support steps higher than 50 @@ -36,6 +36,7 @@ - Reworked **model compile** - Add refiner options to XYZ Grid - Support custom upscalers in subfolders + - Add additional image info when loading image in process tab - Support `--ckpt none` to skip loading a model - **Fixes** - Fix `params.txt` saved before actual image diff --git a/javascript/extraNetworks.js b/javascript/extraNetworks.js index 8415d2d11..9261ffb7d 100644 --- a/javascript/extraNetworks.js +++ b/javascript/extraNetworks.js @@ -40,7 +40,7 @@ const setENState = (state) => { // methods function showCardDetails(event) { - console.log('showCardDetails', event) + console.log('showCardDetails', event); const tabname = getENActiveTab(); const btn = gradioApp().getElementById(`${tabname}_extra_details_btn`); btn.click(); @@ -183,7 +183,7 @@ function sortExtraNetworks() { return `sort page ${pagename} cards ${num} by ${desc}`; } -function refreshExtraNetworks(tabname) { +function refreshENInput(tabname) { log('refreshExtraNetworks', tabname, gradioApp().querySelector(`#${tabname}_extra_networks textarea`)?.value); gradioApp().querySelector(`#${tabname}_extra_networks textarea`)?.dispatchEvent(new Event('input')); } @@ -234,6 +234,27 @@ function quickSaveStyle() { if (btnSave) btnSave.click(); } +let enDirty = false; +function closeDetailsEN(args) { + // log('closeDetailsEN'); + enDirty = true; + const tabname = getENActiveTab(); + const btnClose = gradioApp().getElementById(`${tabname}_extra_details_close`); + if (btnClose) setTimeout(() => btnClose.click(), 100); + const btnRefresh = gradioApp().getElementById(`${tabname}_extra_refresh`); + if (btnRefresh && enDirty) setTimeout(() => btnRefresh.click(), 100); + return args; +} + +function refeshDetailsEN(args) { + log(`refeshDetailsEN: ${enDirty}`); + const tabname = getENActiveTab(); + const btnRefresh = gradioApp().getElementById(`${tabname}_extra_refresh`); + if (btnRefresh && enDirty) setTimeout(() => btnRefresh.click(), 100); + enDirty = false; + return args; +} + // init function setupExtraNetworksForTab(tabname) { diff --git a/modules/images.py b/modules/images.py index 38e7ebbcb..2a02f60bd 100644 --- a/modules/images.py +++ b/modules/images.py @@ -204,6 +204,7 @@ def draw_prompt_matrix(im, width, height, all_prompts, margin=0): def resize_image(resize_mode, im, width, height, upscaler_name=None, output_type='image'): + # shared.log.debug(f'Image resize: mode={resize_mode} resolution={width}x{height} upscaler={upscaler_name}') """ Resizes an image with the specified resize_mode, width, and height. Args: @@ -628,7 +629,7 @@ def safe_decode_string(s: bytes): return None -def read_info_from_image(image): +def read_info_from_image(image: Image): items = image.info or {} geninfo = items.pop('parameters', None) if geninfo is None: @@ -680,6 +681,14 @@ Negative prompt: {json_info["uc"]} Steps: {json_info["steps"]}, Sampler: {sampler}, CFG scale: {json_info["scale"]}, Seed: {json_info["seed"]}, Size: {image.width}x{image.height}, Clip skip: 2, ENSD: 31337""" except Exception as e: errors.display(e, 'novelai image parser') + + try: + items['width'] = image.width + items['height'] = image.height + items['mode'] = image.mode + except Exception as e: + pass + return geninfo, items diff --git a/modules/processing.py b/modules/processing.py index 8a87ea68a..a68e113f8 100644 --- a/modules/processing.py +++ b/modules/processing.py @@ -58,7 +58,7 @@ def apply_color_correction(correction, original_image): return image -def apply_overlay(image, paste_loc, index, overlays): +def apply_overlay(image: Image, paste_loc, index, overlays): if overlays is None or index >= len(overlays): return image overlay = overlays[index] diff --git a/modules/ui_extra_networks.py b/modules/ui_extra_networks.py index 4150fc022..3cd5cdecd 100644 --- a/modules/ui_extra_networks.py +++ b/modules/ui_extra_networks.py @@ -440,6 +440,7 @@ class ExtraNetworksUi: self.details_components: list = [] self.last_item: dict = None self.last_page: ExtraNetworksPage = None + self.state: gr.State = None def create_ui(container, button_parent, tabname, skip_indexing = False): @@ -505,18 +506,18 @@ def create_ui(container, button_parent, tabname, skip_indexing = False): desc = gr.Textbox('', show_label=False, lines=8, placeholder="Extra network description...") ui.details_components.append(desc) with gr.Row(): - btn_save_desc = gr.Button('Save', elem_classes=['small-button']) - btn_delete_desc = gr.Button('Delete', elem_classes=['small-button']) - btn_close_info = gr.Button('Close', elem_classes=['small-button']) - btn_close_info.click(fn=lambda: gr.update(visible=False), inputs=[], outputs=[ui.details]) + btn_save_desc = gr.Button('Save', elem_classes=['small-button'], elem_id=f'{tabname}_extra_details_save_desc') + btn_delete_desc = gr.Button('Delete', elem_classes=['small-button'], elem_id=f'{tabname}_extra_details_delete_desc') + btn_close_desc = gr.Button('Close', elem_classes=['small-button'], elem_id=f'{tabname}_extra_details_close_desc') + btn_close_desc.click(fn=lambda: gr.update(visible=False), _js='refeshDetailsEN', inputs=[], outputs=[ui.details]) with gr.Tab('Model metadata'): info = gr.JSON({}, show_label=False) ui.details_components.append(info) with gr.Row(): - btn_save_info = gr.Button('Save', elem_classes=['small-button']) - btn_delete_info = gr.Button('Delete', elem_classes=['small-button']) - btn_close_info = gr.Button('Close', elem_classes=['small-button']) - btn_close_info.click(fn=lambda: gr.update(visible=False), inputs=[], outputs=[ui.details]) + btn_save_info = gr.Button('Save', elem_classes=['small-button'], elem_id=f'{tabname}_extra_details_save_info') + btn_delete_info = gr.Button('Delete', elem_classes=['small-button'], elem_id=f'{tabname}_extra_details_delete_info') + btn_close_info = gr.Button('Close', elem_classes=['small-button'], elem_id=f'{tabname}_extra_details_close_info') + btn_close_info.click(fn=lambda: gr.update(visible=False), _js='refeshDetailsEN', inputs=[], outputs=[ui.details]) with gr.Tab('Embedded metadata'): meta = gr.JSON({}, show_label=False) ui.details_components.append(meta) @@ -559,7 +560,7 @@ def create_ui(container, button_parent, tabname, skip_indexing = False): tab.select(ui_tab_change, _js="getENActivePage", inputs=[ui.button_details], outputs=[ui.button_scan, ui.button_save, ui.button_model]) # ui.tabs.change(fn=ui_tab_change, inputs=[], outputs=[ui.button_scan, ui.button_save]) - def fn_save_img(): + def fn_save_img(image): if ui.last_item is None or ui.last_item.local_preview is None: return 'html/card-no-preview.png' images = list(ui.gallery.temp_files) # gallery cannot be used as input component so looking at most recently registered temp files @@ -572,7 +573,7 @@ def create_ui(container, button_parent, tabname, skip_indexing = False): except Exception as e: shared.log.error(f'Extra network error opening image: item={ui.last_item.name} {e}') return 'html/card-no-preview.png' - fn_delete_img() + fn_delete_img(image) if image.width > 512 or image.height > 512: image = image.convert('RGB') image.thumbnail((512, 512), Image.HAMMING) @@ -583,7 +584,7 @@ def create_ui(container, button_parent, tabname, skip_indexing = False): shared.log.error(f'Extra network save image: item={ui.last_item.name} filename="{ui.last_item.local_preview}" {e}') return image - def fn_delete_img(): + def fn_delete_img(_image): preview_extensions = ["jpg", "jpeg", "png", "webp", "tiff", "jp2"] fn = os.path.splitext(ui.last_item.filename)[0] for file in [f'{fn}{mid}{ext}' for ext in preview_extensions for mid in ['.thumb.', '.preview.', '.']]: @@ -633,12 +634,12 @@ def create_ui(container, button_parent, tabname, skip_indexing = False): return '' return info - btn_save_img.click(fn=fn_save_img, inputs=[], outputs=[img]) - btn_delete_img.click(fn=fn_delete_img, inputs=[], outputs=[img]) - btn_save_desc.click(fn=fn_save_desc, inputs=[desc], outputs=[desc]) - btn_delete_desc.click(fn=fn_delete_desc, inputs=[desc], outputs=[desc]) - btn_save_info.click(fn=fn_save_info, inputs=[info], outputs=[info]) - btn_delete_info.click(fn=fn_delete_info, inputs=[info], outputs=[info]) + btn_save_img.click(fn=fn_save_img, _js='closeDetailsEN', inputs=[img], outputs=[img]) + btn_delete_img.click(fn=fn_delete_img, _js='closeDetailsEN', inputs=[img], outputs=[img]) + btn_save_desc.click(fn=fn_save_desc, _js='closeDetailsEN', inputs=[desc], outputs=[desc]) + btn_delete_desc.click(fn=fn_delete_desc, _js='closeDetailsEN', inputs=[desc], outputs=[desc]) + btn_save_info.click(fn=fn_save_info, _js='closeDetailsEN', inputs=[info], outputs=[info]) + btn_delete_info.click(fn=fn_delete_info, _js='closeDetailsEN', inputs=[info], outputs=[info]) def show_details(text, img, desc, info, meta, params): page, item = get_item(state, params) @@ -797,7 +798,7 @@ def create_ui(container, button_parent, tabname, skip_indexing = False): shared.log.debug(f'Extra networks: {msg}') return msg - dummy_state = gr.State(value=False) # pylint: disable=abstract-class-instantiated + dummy = gr.State(value=False) # pylint: disable=abstract-class-instantiated button_parent.click(fn=toggle_visibility, inputs=[ui.visible], outputs=[ui.visible, container, button_parent]) ui.button_close.click(fn=toggle_visibility, inputs=[ui.visible], outputs=[ui.visible, container]) ui.button_sort.click(fn=ui_sort_cards, _js='sortExtraNetworks', inputs=[ui.search], outputs=[ui.description]) @@ -806,7 +807,7 @@ def create_ui(container, button_parent, tabname, skip_indexing = False): ui.button_scan.click(fn=ui_scan_click, _js='getENActivePage', inputs=[ui.search], outputs=ui.pages) ui.button_save.click(fn=ui_save_click, inputs=[], outputs=ui.details_components + [ui.details]) ui.button_quicksave.click(fn=ui_quicksave_click, _js="() => prompt('Prompt name', '')", inputs=[ui.search], outputs=[]) - ui.button_details.click(show_details, _js="getCardDetails", inputs=ui.details_components + [dummy_state], outputs=ui.details_components + [ui.details]) + ui.button_details.click(show_details, _js="getCardDetails", inputs=ui.details_components + [dummy], outputs=ui.details_components + [ui.details]) ui.state.change(state_change, inputs=[ui.state], outputs=[]) return ui