diff --git a/README.md b/README.md index c5785af..897a5d3 100644 --- a/README.md +++ b/README.md @@ -53,10 +53,10 @@ Support me and my work : ❤️❤️❤️ ❤️ `116.` [📥 Load Text From Path](#116----load-text-from-path) `117.` [📝👈🅰️ Line selector (🎲 or ♻ or ♻📑)](#117---🅰%EF%B8%8F-line-selector--or--or-) `131.` [✒👉 Write Pick Me Chain](#131----write-pick-me-chain) -`136.` [🔛📝 Text Switch On/Off](#136) -`138.` [📑👈 Select from List](#138) -`141.` [🌎✒👉 Global Write Pick Me](#141) -`142.` [🌎📥 Load Global Pick Me](#142) +`136.` [🔛📝 Text Switch On/Off](#136----text-switch-onoff) +`138.` [📑👈 Select from List](#138----select-from-list) +`141.` [🌎✒👉 Global Write Pick Me](#141----global-write-pick-me) +`142.` [🌎📥 Load Global Pick Me](#142----load-global-pick-me) ## 🔥 Text Generator 🔥 `81.` [🔥📝 Text Generator 📝🔥](#81----text-generator-) @@ -113,8 +113,8 @@ Support me and my work : ❤️❤️❤️ ❤️ `48.` [🔀🎲 Text scrambler (🧑 Character)](#48----text-scrambler--character) `55.` [🎲👑 Random Lora Selector](#55----random-lora-selector) `117.` [📝👈🅰️ Line selector (🎲 or ♻ or ♻📑)](#117---🅰%EF%B8%8F-line-selector--or--or-) -`139.` [🎲 Random Integer](#139) -`140.` [🎲 Random Float](#140) +`139.` [🎲 Random Integer](#139----random-integer) +`140.` [🎲 Random Float](#140----random-float) ## 🖼💾 Save Image / Text 💾🖼 `16.` [💾🖼💬 Save image for Bjornulf LobeChat](#16----save-image-for-bjornulf-lobechat-for-my-custom-lobe-chat) @@ -221,17 +221,17 @@ Support me and my work : ❤️❤️❤️ ❤️ `66.` [🔊➜📝 STT - Speech to Text](#66----stt---speech-to-text) `118.` [🔊 TTS Configuration ⚙](#118----tts-configuration-) `120.` [📝➜🔊 Kokoro - Text to Speech](#120----kokoro---text-to-speech) -`134.` [134 - 🔊▶ Play Audio](#134) +`134.` [134 - 🔊▶ Play Audio](#134----play-audio) ## 💻 General / System 💻 `34.` [🧹 Free VRAM hack](#34----free-vram-hack) -`137.` [🌎🎲 Global Seed Manager](#137) +`137.` [🌎🎲 Global Seed Manager](#137----global-seed-manager) ## 🧍 Manual user Control 🧍 `35.` [⏸️ Paused. Resume or Stop, Pick 👇](#35---%EF%B8%8F-paused-resume-or-stop-) `36.` [⏸️ Paused. Select input, Pick 👇](#36---%EF%B8%8F-paused-select-input-pick-one) `117.` [📝👈🅰️ Line selector (🎲 or ♻ or ♻📑)](#117---🅰%EF%B8%8F-line-selector--or--or-) -`135.` [🔛✨ Anything Switch On/Off](#135) +`135.` [🔛✨ Anything Switch On/Off](#135----anything-switch-onoff) ## 🧠 Logic / Conditional Operations 🧠 `45.` [🔀 If-Else (input / compare_with)](#45----if-else-input--compare_with) diff --git a/hugginface_download.py b/hugginface_download.py index c64767a..27e82e8 100644 --- a/hugginface_download.py +++ b/hugginface_download.py @@ -1,14 +1,18 @@ import os import folder_paths from huggingface_hub import hf_hub_download +from huggingface_hub.utils import EntryNotFoundError class HuggingFaceDownloader: """Custom node for downloading models from Hugging Face within ComfyUI""" + # Mapping of model types to their directory names MODELS_DIR = { "models/vae": "vae", "models/unet": "unet", "models/clip": "clip", + "models/text_encoders": "text_encoders", + "models/diffusion_models": "diffusion_models", "models/lora": "loras", "models/controlnet": "controlnet", "models/upscale": "upscale_models", @@ -37,27 +41,58 @@ class HuggingFaceDownloader: def download_model(self, hf_token, repo_id, filename, model_type, custom_path=None): download_dir = "Unknown" try: + # Set the Hugging Face token os.environ["HF_TOKEN"] = hf_token + # Determine the download directory if custom_path: download_dir = custom_path else: folder_key = self.MODELS_DIR[model_type] download_dir = folder_paths.get_folder_paths(folder_key)[0] + # Create the download directory if it doesn’t exist os.makedirs(download_dir, exist_ok=True) - hf_hub_download( - repo_id=repo_id, - filename=filename, - token=hf_token, - local_dir=download_dir - ) + # Progress callback to show download progress + def progress_callback(downloaded, total): + if total > 0: + progress = (downloaded / total) * 100 + print(f"\rDownloading {filename}: {progress:.2f}%", end="") + if downloaded == total: + print("\nDownload complete.") - return (f"Successfully downloaded {filename} to {download_dir}",) + # First attempt: try downloading the file directly from the repository + try: + hf_hub_download( + repo_id=repo_id, + filename=filename, + subfolder=None, + token=hf_token, + local_dir=download_dir, + callbacks=[progress_callback] + ) + source = "directly" + except EntryNotFoundError: + # Second attempt: try downloading from split_files/ + subfolder = f"split_files/{self.MODELS_DIR[model_type]}" + hf_hub_download( + repo_id=repo_id, + filename=filename, + subfolder=subfolder, + token=hf_token, + local_dir=download_dir, + callbacks=[progress_callback] + ) + source = f"subfolder {subfolder}" + + # Return success message with the source of the file + return (f"Successfully downloaded {filename} from {repo_id} ({source}) to {download_dir}",) except IndexError: return (f"No directory found for model type: {model_type}. Check folder_paths configuration.",) + except EntryNotFoundError: + return (f"Error: {filename} not found in {repo_id} or {repo_id}/split_files/{self.MODELS_DIR[model_type]}",) except Exception as e: return (f"Error downloading model: {str(e)}, {filename} to {download_dir}",) diff --git a/image_details.py b/image_details.py index 6454a43..d7b761c 100644 --- a/image_details.py +++ b/image_details.py @@ -87,6 +87,7 @@ class ImageDetails: details = f"\nType: {input_type}" details += f"\nWidth: {width}" details += f"\nHeight: {height}" + details += f"\nNumber of Pixels: {width * height}" details += f"\nLoaded with transparency: {has_transparency}" details += f"\nImage Mode: {pil_image.mode}" details += f"\nOrientation: {orientation}\n" diff --git a/resize_image.py b/resize_image.py index 432f2ae..1804313 100644 --- a/resize_image.py +++ b/resize_image.py @@ -23,6 +23,30 @@ class ResizeImage: # Ensure the input image is on CPU and convert to numpy array image_np = image.cpu().numpy() + # Get original dimensions + if image_np.ndim == 4: + orig_height, orig_width = image_np.shape[1:3] + else: + orig_height, orig_width = image_np.shape[:2] + + # Calculate new dimensions maintaining aspect ratio if needed + aspect_ratio = orig_width / orig_height + + if width == 0 and height == 0: + # If both are 0, use original dimensions + new_width, new_height = orig_width, orig_height + elif width == 0: + # If width is 0, calculate it based on height + new_height = height + new_width = int(height * aspect_ratio) + elif height == 0: + # If height is 0, calculate it based on width + new_width = width + new_height = int(width / aspect_ratio) + else: + # Use provided dimensions + new_width, new_height = width, height + # Check if the image is in the format [batch, height, width, channel] if image_np.ndim == 4: # If so, we'll process each image in the batch @@ -31,7 +55,7 @@ class ResizeImage: # Convert to PIL Image pil_img = Image.fromarray((img * 255).astype(np.uint8)) # Resize - resized_pil = pil_img.resize((width, height), Image.LANCZOS) + resized_pil = pil_img.resize((new_width, new_height), Image.LANCZOS) # Convert back to numpy and normalize resized_np = np.array(resized_pil).astype(np.float32) / 255.0 resized_images.append(resized_np) @@ -45,7 +69,7 @@ class ResizeImage: # Convert to PIL Image pil_img = Image.fromarray((image_np * 255).astype(np.uint8)) # Resize - resized_pil = pil_img.resize((width, height), Image.LANCZOS) + resized_pil = pil_img.resize((new_width, new_height), Image.LANCZOS) # Convert back to numpy and normalize resized_np = np.array(resized_pil).astype(np.float32) / 255.0 # Add batch dimension if it was originally present @@ -56,7 +80,7 @@ class ResizeImage: # Update metadata if needed if extra_pnginfo is not None: - extra_pnginfo["resized_width"] = width - extra_pnginfo["resized_height"] = height + extra_pnginfo["resized_width"] = new_width + extra_pnginfo["resized_height"] = new_height return (resized_tensor, prompt, extra_pnginfo) \ No newline at end of file