diff --git a/README.md b/README.md index 05ede55..45ff373 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ Visual multi-LoRA loader with a thumbnail grid browser, selected-LoRA panel, and **SFW toggle:** When enabled, any folder named `NSFW` (case-insensitive) is hidden from browse and search — at any depth in your LoRA library. Turn it off to show those folders again. -**Thumbnails:** place `{lora_name}.png` next to each `.safetensors` file. Right-click a **Preview Image** → **Save as LoRA thumbnail** to save from a generated image (overwrites existing). +**Thumbnails:** place an image next to each `.safetensors` file using the same base name — `.png`, `.webp`, `.jpg`, or `.jpeg` (`.png` is preferred when multiple exist). Right-click a **Preview Image** → **Save as LoRA thumbnail** to save from a generated image (saved as `.png`, overwrites existing). **Trigger words:** companion `.txt` file beside the LoRA (same base name). One per line or comma-separated. diff --git a/lora_browser.py b/lora_browser.py index b9b9d4c..a6eba32 100644 --- a/lora_browser.py +++ b/lora_browser.py @@ -10,12 +10,12 @@ import folder_paths from .lora_info_service import get_lora_info from .nodes.lora_utils import ( _resolve_lora_full_path, + find_lora_preview_path, get_lora_triggers, lora_has_preview, normalize_lora_path, ) -IMAGE_EXTENSIONS = {".png", ".jpg", ".jpeg", ".webp", ".gif", ".bmp"} NSFW_FOLDER_NAME = "nsfw" @@ -237,15 +237,7 @@ def _search_loras(relative_path: str, query: str, sfw: bool = True) -> list[dict def _find_preview_image(lora_relative_path: str) -> str | None: full_path = _resolve_lora_path(lora_relative_path) - if full_path is None: - return None - - base, _ = os.path.splitext(full_path) - for ext in IMAGE_EXTENSIONS: - candidate = f"{base}{ext}" - if os.path.isfile(candidate): - return candidate - return None + return find_lora_preview_path(full_path) def _preview_cache_headers(source_path: str) -> dict[str, str]: diff --git a/nodes/lora_utils.py b/nodes/lora_utils.py index 31e9131..e9a3b0d 100644 --- a/nodes/lora_utils.py +++ b/nodes/lora_utils.py @@ -219,13 +219,25 @@ def get_lora_by_filename(file_path: str, lora_paths=None) -> str | None: return None +LORA_PREVIEW_EXTENSIONS = (".png", ".webp", ".jpg", ".jpeg", ".gif", ".bmp") + + +def find_lora_preview_path(full_path: str | None) -> str | None: + if not full_path: + return None + + base, _ = os.path.splitext(full_path) + for ext in LORA_PREVIEW_EXTENSIONS: + candidate = f"{base}{ext}" + if os.path.isfile(candidate): + return candidate + return None + + def lora_has_preview(lora_relative_path: str, *, full_path: str | None = None) -> bool: if full_path is None: full_path = _resolve_lora_full_path(lora_relative_path) - if full_path is None: - return False - base, _ = os.path.splitext(full_path) - return os.path.isfile(f"{base}.png") + return find_lora_preview_path(full_path) is not None def get_lora_triggers(lora_relative_path: str = "", *, full_path: str | None = None) -> list[str]: