mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-21 13:12:12 -03:00
Merge pull request #862 from EnragedAntelope/claude/add-webp-image-support-t8kG9
Improve webp image support
This commit is contained in:
3
package-lock.json
generated
3
package-lock.json
generated
@@ -114,7 +114,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
},
|
},
|
||||||
@@ -138,7 +137,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
}
|
}
|
||||||
@@ -1613,7 +1611,6 @@
|
|||||||
"integrity": "sha512-MyL55p3Ut3cXbeBEG7Hcv0mVM8pp8PBNWxRqchZnSfAiES1v1mRnMeFfaHWIPULpwsYfvO+ZmMZz5tGCnjzDUQ==",
|
"integrity": "sha512-MyL55p3Ut3cXbeBEG7Hcv0mVM8pp8PBNWxRqchZnSfAiES1v1mRnMeFfaHWIPULpwsYfvO+ZmMZz5tGCnjzDUQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cssstyle": "^4.0.1",
|
"cssstyle": "^4.0.1",
|
||||||
"data-urls": "^5.0.0",
|
"data-urls": "^5.0.0",
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ from ..utils.metadata_manager import MetadataManager
|
|||||||
from ..utils.civitai_utils import resolve_license_info
|
from ..utils.civitai_utils import resolve_license_info
|
||||||
from .model_cache import ModelCache
|
from .model_cache import ModelCache
|
||||||
from .model_hash_index import ModelHashIndex
|
from .model_hash_index import ModelHashIndex
|
||||||
from ..utils.constants import PREVIEW_EXTENSIONS
|
|
||||||
from .model_lifecycle_service import delete_model_artifacts
|
from .model_lifecycle_service import delete_model_artifacts
|
||||||
from .service_registry import ServiceRegistry
|
from .service_registry import ServiceRegistry
|
||||||
from .websocket_manager import ws_manager
|
from .websocket_manager import ws_manager
|
||||||
@@ -1442,14 +1441,13 @@ class ModelScanner:
|
|||||||
file_path = self._hash_index.get_path(sha256.lower())
|
file_path = self._hash_index.get_path(sha256.lower())
|
||||||
if not file_path:
|
if not file_path:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
base_name = os.path.splitext(file_path)[0]
|
dir_path = os.path.dirname(file_path)
|
||||||
|
base_name = os.path.splitext(os.path.basename(file_path))[0]
|
||||||
for ext in PREVIEW_EXTENSIONS:
|
preview_path = find_preview_file(base_name, dir_path)
|
||||||
preview_path = f"{base_name}{ext}"
|
if preview_path:
|
||||||
if os.path.exists(preview_path):
|
return config.get_preview_static_url(preview_path)
|
||||||
return config.get_preview_static_url(preview_path)
|
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
async def get_top_tags(self, limit: int = 20) -> List[Dict[str, any]]:
|
async def get_top_tags(self, limit: int = 20) -> List[Dict[str, any]]:
|
||||||
|
|||||||
@@ -40,49 +40,39 @@ async def calculate_sha256(file_path: str) -> str:
|
|||||||
return sha256_hash.hexdigest()
|
return sha256_hash.hexdigest()
|
||||||
|
|
||||||
def find_preview_file(base_name: str, dir_path: str) -> str:
|
def find_preview_file(base_name: str, dir_path: str) -> str:
|
||||||
"""Find preview file for given base name in directory"""
|
"""Find preview file for given base name in directory.
|
||||||
|
|
||||||
|
Performs an exact-case check first (fast path), then falls back to a
|
||||||
|
case-insensitive scan so that files like ``model.WEBP`` or ``model.Png``
|
||||||
|
are discovered on case-sensitive filesystems.
|
||||||
|
"""
|
||||||
|
|
||||||
temp_extensions = PREVIEW_EXTENSIONS.copy()
|
temp_extensions = PREVIEW_EXTENSIONS.copy()
|
||||||
# Add example extension for compatibility
|
# Add example extension for compatibility
|
||||||
# https://github.com/willmiao/ComfyUI-Lora-Manager/issues/225
|
# https://github.com/willmiao/ComfyUI-Lora-Manager/issues/225
|
||||||
# The preview image will be optimized to lora-name.webp, so it won't affect other logic
|
# The preview image will be optimized to lora-name.webp, so it won't affect other logic
|
||||||
temp_extensions.append(".example.0.jpeg")
|
temp_extensions.append(".example.0.jpeg")
|
||||||
|
|
||||||
|
# Fast path: exact-case match
|
||||||
for ext in temp_extensions:
|
for ext in temp_extensions:
|
||||||
full_pattern = os.path.join(dir_path, f"{base_name}{ext}")
|
full_pattern = os.path.join(dir_path, f"{base_name}{ext}")
|
||||||
if os.path.exists(full_pattern):
|
if os.path.exists(full_pattern):
|
||||||
# Check if this is an image and not already webp
|
|
||||||
# TODO: disable the optimization for now, maybe add a config option later
|
|
||||||
# if ext.lower().endswith(('.jpg', '.jpeg', '.png')) and not ext.lower().endswith('.webp'):
|
|
||||||
# try:
|
|
||||||
# # Optimize the image to webp format
|
|
||||||
# webp_path = os.path.join(dir_path, f"{base_name}.webp")
|
|
||||||
|
|
||||||
# # Use ExifUtils to optimize the image
|
|
||||||
# with open(full_pattern, 'rb') as f:
|
|
||||||
# image_data = f.read()
|
|
||||||
|
|
||||||
# optimized_data, _ = ExifUtils.optimize_image(
|
|
||||||
# image_data=image_data,
|
|
||||||
# target_width=CARD_PREVIEW_WIDTH,
|
|
||||||
# format='webp',
|
|
||||||
# quality=85,
|
|
||||||
# preserve_metadata=False
|
|
||||||
# )
|
|
||||||
|
|
||||||
# # Save the optimized webp file
|
|
||||||
# with open(webp_path, 'wb') as f:
|
|
||||||
# f.write(optimized_data)
|
|
||||||
|
|
||||||
# logger.debug(f"Optimized preview image from {full_pattern} to {webp_path}")
|
|
||||||
# return webp_path.replace(os.sep, "/")
|
|
||||||
# except Exception as e:
|
|
||||||
# logger.error(f"Error optimizing preview image {full_pattern}: {e}")
|
|
||||||
# # Fall back to original file if optimization fails
|
|
||||||
# return full_pattern.replace(os.sep, "/")
|
|
||||||
|
|
||||||
# Return the original path for webp images or non-image files
|
|
||||||
return full_pattern.replace(os.sep, "/")
|
return full_pattern.replace(os.sep, "/")
|
||||||
|
|
||||||
|
# Slow path: case-insensitive match for systems with mixed-case extensions
|
||||||
|
# (e.g. .WEBP, .Png, .JPG placed manually or by external tools)
|
||||||
|
try:
|
||||||
|
dir_entries = os.listdir(dir_path)
|
||||||
|
except OSError:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
base_lower = base_name.lower()
|
||||||
|
for ext in temp_extensions:
|
||||||
|
target = f"{base_lower}{ext}" # ext is already lowercase
|
||||||
|
for entry in dir_entries:
|
||||||
|
if entry.lower() == target:
|
||||||
|
return os.path.join(dir_path, entry).replace(os.sep, "/")
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
def get_preview_extension(preview_path: str) -> str:
|
def get_preview_extension(preview_path: str) -> str:
|
||||||
|
|||||||
@@ -251,7 +251,7 @@ export class BaseModelApiClient {
|
|||||||
replaceModelPreview(filePath) {
|
replaceModelPreview(filePath) {
|
||||||
const input = document.createElement('input');
|
const input = document.createElement('input');
|
||||||
input.type = 'file';
|
input.type = 'file';
|
||||||
input.accept = 'image/*,video/mp4';
|
input.accept = 'image/*,image/webp,video/mp4';
|
||||||
|
|
||||||
input.onchange = async () => {
|
input.onchange = async () => {
|
||||||
if (!input.files || !input.files[0]) return;
|
if (!input.files || !input.files[0]) return;
|
||||||
|
|||||||
Reference in New Issue
Block a user