mirror of
https://github.com/justUmen/Bjornulf_custom_nodes.git
synced 2026-03-21 12:42: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)
|
||||
`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 : ❤️❤️❤️ <https://ko-fi.com/bjornulf> ❤️
|
||||
`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 : ❤️❤️❤️ <https://ko-fi.com/bjornulf> ❤️
|
||||
`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)
|
||||
|
||||
@@ -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/<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:
|
||||
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}",)
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
Reference in New Issue
Block a user