mirror of
https://github.com/justUmen/Bjornulf_custom_nodes.git
synced 2026-03-21 20:52:11 -03:00
...
This commit is contained in:
18
README.md
18
README.md
@@ -53,10 +53,10 @@ Support me and my work : ❤️❤️❤️ <https://ko-fi.com/bjornulf> ❤️
|
|||||||
`116.` [📥 Load Text From Path](#116----load-text-from-path)
|
`116.` [📥 Load Text From Path](#116----load-text-from-path)
|
||||||
`117.` [📝👈🅰️ Line selector (🎲 or ♻ or ♻📑)](#117---🅰%EF%B8%8F-line-selector--or--or-)
|
`117.` [📝👈🅰️ Line selector (🎲 or ♻ or ♻📑)](#117---🅰%EF%B8%8F-line-selector--or--or-)
|
||||||
`131.` [✒👉 Write Pick Me Chain](#131----write-pick-me-chain)
|
`131.` [✒👉 Write Pick Me Chain](#131----write-pick-me-chain)
|
||||||
`136.` [🔛📝 Text Switch On/Off](#136)
|
`136.` [🔛📝 Text Switch On/Off](#136----text-switch-onoff)
|
||||||
`138.` [📑👈 Select from List](#138)
|
`138.` [📑👈 Select from List](#138----select-from-list)
|
||||||
`141.` [🌎✒👉 Global Write Pick Me](#141)
|
`141.` [🌎✒👉 Global Write Pick Me](#141----global-write-pick-me)
|
||||||
`142.` [🌎📥 Load Global Pick Me](#142)
|
`142.` [🌎📥 Load Global Pick Me](#142----load-global-pick-me)
|
||||||
|
|
||||||
## 🔥 Text Generator 🔥
|
## 🔥 Text Generator 🔥
|
||||||
`81.` [🔥📝 Text Generator 📝🔥](#81----text-generator-)
|
`81.` [🔥📝 Text Generator 📝🔥](#81----text-generator-)
|
||||||
@@ -113,8 +113,8 @@ Support me and my work : ❤️❤️❤️ <https://ko-fi.com/bjornulf> ❤️
|
|||||||
`48.` [🔀🎲 Text scrambler (🧑 Character)](#48----text-scrambler--character)
|
`48.` [🔀🎲 Text scrambler (🧑 Character)](#48----text-scrambler--character)
|
||||||
`55.` [🎲👑 Random Lora Selector](#55----random-lora-selector)
|
`55.` [🎲👑 Random Lora Selector](#55----random-lora-selector)
|
||||||
`117.` [📝👈🅰️ Line selector (🎲 or ♻ or ♻📑)](#117---🅰%EF%B8%8F-line-selector--or--or-)
|
`117.` [📝👈🅰️ Line selector (🎲 or ♻ or ♻📑)](#117---🅰%EF%B8%8F-line-selector--or--or-)
|
||||||
`139.` [🎲 Random Integer](#139)
|
`139.` [🎲 Random Integer](#139----random-integer)
|
||||||
`140.` [🎲 Random Float](#140)
|
`140.` [🎲 Random Float](#140----random-float)
|
||||||
|
|
||||||
## 🖼💾 Save Image / Text 💾🖼
|
## 🖼💾 Save Image / Text 💾🖼
|
||||||
`16.` [💾🖼💬 Save image for Bjornulf LobeChat](#16----save-image-for-bjornulf-lobechat-for-my-custom-lobe-chat)
|
`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 : ❤️❤️❤️ <https://ko-fi.com/bjornulf> ❤️
|
|||||||
`66.` [🔊➜📝 STT - Speech to Text](#66----stt---speech-to-text)
|
`66.` [🔊➜📝 STT - Speech to Text](#66----stt---speech-to-text)
|
||||||
`118.` [🔊 TTS Configuration ⚙](#118----tts-configuration-)
|
`118.` [🔊 TTS Configuration ⚙](#118----tts-configuration-)
|
||||||
`120.` [📝➜🔊 Kokoro - Text to Speech](#120----kokoro---text-to-speech)
|
`120.` [📝➜🔊 Kokoro - Text to Speech](#120----kokoro---text-to-speech)
|
||||||
`134.` [134 - 🔊▶ Play Audio](#134)
|
`134.` [134 - 🔊▶ Play Audio](#134----play-audio)
|
||||||
|
|
||||||
## 💻 General / System 💻
|
## 💻 General / System 💻
|
||||||
`34.` [🧹 Free VRAM hack](#34----free-vram-hack)
|
`34.` [🧹 Free VRAM hack](#34----free-vram-hack)
|
||||||
`137.` [🌎🎲 Global Seed Manager](#137)
|
`137.` [🌎🎲 Global Seed Manager](#137----global-seed-manager)
|
||||||
|
|
||||||
## 🧍 Manual user Control 🧍
|
## 🧍 Manual user Control 🧍
|
||||||
`35.` [⏸️ Paused. Resume or Stop, Pick 👇](#35---%EF%B8%8F-paused-resume-or-stop-)
|
`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)
|
`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-)
|
`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 🧠
|
## 🧠 Logic / Conditional Operations 🧠
|
||||||
`45.` [🔀 If-Else (input / compare_with)](#45----if-else-input--compare_with)
|
`45.` [🔀 If-Else (input / compare_with)](#45----if-else-input--compare_with)
|
||||||
|
|||||||
@@ -1,14 +1,18 @@
|
|||||||
import os
|
import os
|
||||||
import folder_paths
|
import folder_paths
|
||||||
from huggingface_hub import hf_hub_download
|
from huggingface_hub import hf_hub_download
|
||||||
|
from huggingface_hub.utils import EntryNotFoundError
|
||||||
|
|
||||||
class HuggingFaceDownloader:
|
class HuggingFaceDownloader:
|
||||||
"""Custom node for downloading models from Hugging Face within ComfyUI"""
|
"""Custom node for downloading models from Hugging Face within ComfyUI"""
|
||||||
|
|
||||||
|
# Mapping of model types to their directory names
|
||||||
MODELS_DIR = {
|
MODELS_DIR = {
|
||||||
"models/vae": "vae",
|
"models/vae": "vae",
|
||||||
"models/unet": "unet",
|
"models/unet": "unet",
|
||||||
"models/clip": "clip",
|
"models/clip": "clip",
|
||||||
|
"models/text_encoders": "text_encoders",
|
||||||
|
"models/diffusion_models": "diffusion_models",
|
||||||
"models/lora": "loras",
|
"models/lora": "loras",
|
||||||
"models/controlnet": "controlnet",
|
"models/controlnet": "controlnet",
|
||||||
"models/upscale": "upscale_models",
|
"models/upscale": "upscale_models",
|
||||||
@@ -37,27 +41,58 @@ class HuggingFaceDownloader:
|
|||||||
def download_model(self, hf_token, repo_id, filename, model_type, custom_path=None):
|
def download_model(self, hf_token, repo_id, filename, model_type, custom_path=None):
|
||||||
download_dir = "Unknown"
|
download_dir = "Unknown"
|
||||||
try:
|
try:
|
||||||
|
# Set the Hugging Face token
|
||||||
os.environ["HF_TOKEN"] = hf_token
|
os.environ["HF_TOKEN"] = hf_token
|
||||||
|
|
||||||
|
# Determine the download directory
|
||||||
if custom_path:
|
if custom_path:
|
||||||
download_dir = custom_path
|
download_dir = custom_path
|
||||||
else:
|
else:
|
||||||
folder_key = self.MODELS_DIR[model_type]
|
folder_key = self.MODELS_DIR[model_type]
|
||||||
download_dir = folder_paths.get_folder_paths(folder_key)[0]
|
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)
|
os.makedirs(download_dir, exist_ok=True)
|
||||||
|
|
||||||
hf_hub_download(
|
# Progress callback to show download progress
|
||||||
repo_id=repo_id,
|
def progress_callback(downloaded, total):
|
||||||
filename=filename,
|
if total > 0:
|
||||||
token=hf_token,
|
progress = (downloaded / total) * 100
|
||||||
local_dir=download_dir
|
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/<model_type>
|
||||||
|
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:
|
except IndexError:
|
||||||
return (f"No directory found for model type: {model_type}. Check folder_paths configuration.",)
|
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:
|
except Exception as e:
|
||||||
return (f"Error downloading model: {str(e)}, {filename} to {download_dir}",)
|
return (f"Error downloading model: {str(e)}, {filename} to {download_dir}",)
|
||||||
|
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ class ImageDetails:
|
|||||||
details = f"\nType: {input_type}"
|
details = f"\nType: {input_type}"
|
||||||
details += f"\nWidth: {width}"
|
details += f"\nWidth: {width}"
|
||||||
details += f"\nHeight: {height}"
|
details += f"\nHeight: {height}"
|
||||||
|
details += f"\nNumber of Pixels: {width * height}"
|
||||||
details += f"\nLoaded with transparency: {has_transparency}"
|
details += f"\nLoaded with transparency: {has_transparency}"
|
||||||
details += f"\nImage Mode: {pil_image.mode}"
|
details += f"\nImage Mode: {pil_image.mode}"
|
||||||
details += f"\nOrientation: {orientation}\n"
|
details += f"\nOrientation: {orientation}\n"
|
||||||
|
|||||||
@@ -23,6 +23,30 @@ class ResizeImage:
|
|||||||
# Ensure the input image is on CPU and convert to numpy array
|
# Ensure the input image is on CPU and convert to numpy array
|
||||||
image_np = image.cpu().numpy()
|
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]
|
# Check if the image is in the format [batch, height, width, channel]
|
||||||
if image_np.ndim == 4:
|
if image_np.ndim == 4:
|
||||||
# If so, we'll process each image in the batch
|
# If so, we'll process each image in the batch
|
||||||
@@ -31,7 +55,7 @@ class ResizeImage:
|
|||||||
# Convert to PIL Image
|
# Convert to PIL Image
|
||||||
pil_img = Image.fromarray((img * 255).astype(np.uint8))
|
pil_img = Image.fromarray((img * 255).astype(np.uint8))
|
||||||
# Resize
|
# 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
|
# Convert back to numpy and normalize
|
||||||
resized_np = np.array(resized_pil).astype(np.float32) / 255.0
|
resized_np = np.array(resized_pil).astype(np.float32) / 255.0
|
||||||
resized_images.append(resized_np)
|
resized_images.append(resized_np)
|
||||||
@@ -45,7 +69,7 @@ class ResizeImage:
|
|||||||
# Convert to PIL Image
|
# Convert to PIL Image
|
||||||
pil_img = Image.fromarray((image_np * 255).astype(np.uint8))
|
pil_img = Image.fromarray((image_np * 255).astype(np.uint8))
|
||||||
# Resize
|
# 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
|
# Convert back to numpy and normalize
|
||||||
resized_np = np.array(resized_pil).astype(np.float32) / 255.0
|
resized_np = np.array(resized_pil).astype(np.float32) / 255.0
|
||||||
# Add batch dimension if it was originally present
|
# Add batch dimension if it was originally present
|
||||||
@@ -56,7 +80,7 @@ class ResizeImage:
|
|||||||
|
|
||||||
# Update metadata if needed
|
# Update metadata if needed
|
||||||
if extra_pnginfo is not None:
|
if extra_pnginfo is not None:
|
||||||
extra_pnginfo["resized_width"] = width
|
extra_pnginfo["resized_width"] = new_width
|
||||||
extra_pnginfo["resized_height"] = height
|
extra_pnginfo["resized_height"] = new_height
|
||||||
|
|
||||||
return (resized_tensor, prompt, extra_pnginfo)
|
return (resized_tensor, prompt, extra_pnginfo)
|
||||||
Reference in New Issue
Block a user