mirror of
https://github.com/justUmen/Bjornulf_custom_nodes.git
synced 2026-03-21 20:52:11 -03:00
0.28
This commit is contained in:
44
README.md
44
README.md
@@ -1,4 +1,4 @@
|
|||||||
# 🔗 Comfyui : Bjornulf_custom_nodes v0.26 🔗
|
# 🔗 Comfyui : Bjornulf_custom_nodes v0.28 🔗
|
||||||
|
|
||||||
# ❤️ Coffee : ☕☕☕☕☕ 5/5
|
# ❤️ Coffee : ☕☕☕☕☕ 5/5
|
||||||
|
|
||||||
@@ -74,10 +74,12 @@ wget --content-disposition -P /workspace/ComfyUI/models/checkpoints "https://civ
|
|||||||
- **v0.24**: Add a new node: Pause, select input, pick one.
|
- **v0.24**: Add a new node: Pause, select input, pick one.
|
||||||
- **v0.25**: Two new nodes: Loop Images and Random image.
|
- **v0.25**: Two new nodes: Loop Images and Random image.
|
||||||
- **v0.26**: New node : Loop write Text. Also increase nb of inputs allowed for most nodes. (+ update some breaking changes)
|
- **v0.26**: New node : Loop write Text. Also increase nb of inputs allowed for most nodes. (+ update some breaking changes)
|
||||||
|
- **v0.27**: Two new nodes : Loop (Model+Clip+Vae) and Random (Model+Clip+Vae) - aka Checkpoint / Model
|
||||||
|
- **v0.28**: Fix random texts and add a lot of screenshots examples for several nodes.
|
||||||
|
|
||||||
# 📝 Nodes descriptions
|
# 📝 Nodes descriptions
|
||||||
|
|
||||||
## 1/2 - 👁 + ✒ Show/Write Text
|
## 1/1b/2 - 👁 + ✒ Show/Write Text
|
||||||

|

|
||||||

|

|
||||||

|

|
||||||
@@ -99,6 +101,7 @@ Combine multiple text inputs into a single output. (can have separation with : c
|
|||||||
|
|
||||||
**Description:**
|
**Description:**
|
||||||
Generate and display random text from a predefined list. Great for creating random prompts.
|
Generate and display random text from a predefined list. Great for creating random prompts.
|
||||||
|
You can change fixed/randomize for `control_after_generate` to have a different text each time you run the workflow. (or not)
|
||||||
|
|
||||||
## 5 - ♻ Loop
|
## 5 - ♻ Loop
|
||||||

|

|
||||||
@@ -112,6 +115,8 @@ General-purpose loop node.
|
|||||||
**Description:**
|
**Description:**
|
||||||
Cycle through a list of text inputs.
|
Cycle through a list of text inputs.
|
||||||
|
|
||||||
|
Here is an example of usage with combine texts and flux :
|
||||||
|

|
||||||
|
|
||||||
## 7 - ♻ Loop Integer
|
## 7 - ♻ Loop Integer
|
||||||

|

|
||||||
@@ -123,10 +128,9 @@ Iterate through a range of integer values, good for `steps` in ksampler, etc...
|
|||||||
❗ Don't forget that you can convert ksampler widgets to input by right-clicking the ksampler node :
|
❗ Don't forget that you can convert ksampler widgets to input by right-clicking the ksampler node :
|
||||||

|

|
||||||
|
|
||||||
Here is an example of usage with ksampler (Notice that it isn't optimized, but good enough for testing) :
|
Here is an example of usage with ksampler (Notice that with "steps" this node isn't optimized, but good enough for quick testing.) :
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
## 8 - ♻ Loop Float
|
## 8 - ♻ Loop Float
|
||||||

|

|
||||||

|

|
||||||
@@ -134,17 +138,23 @@ Here is an example of usage with ksampler (Notice that it isn't optimized, but g
|
|||||||
**Description:**
|
**Description:**
|
||||||
Loop through a range of floating-point numbers, good for `cfg`, `denoise`, etc...
|
Loop through a range of floating-point numbers, good for `cfg`, `denoise`, etc...
|
||||||
|
|
||||||
|
Here is an example with controlnet, trying to make a red cat based on a blue rabbit :
|
||||||
|

|
||||||
|
|
||||||
## 10 - ♻ Loop All Samplers
|
## 10 - ♻ Loop All Samplers
|
||||||

|

|
||||||
|
|
||||||
**Description:**
|
**Description:**
|
||||||
Iterate over all available samplers to apply them sequentially. Ideal for testing.
|
Iterate over all available samplers to apply them sequentially. Ideal for testing.
|
||||||
|
|
||||||
|
Here is an example of looping over all the samplers with the normal scheduler :
|
||||||
|

|
||||||
|
|
||||||
## 11 - ♻ Loop All Schedulers
|
## 11 - ♻ Loop All Schedulers
|
||||||

|

|
||||||
|
|
||||||
**Description:**
|
**Description:**
|
||||||
Iterate over all available schedulers to apply them sequentially. Ideal for testing.
|
Iterate over all available schedulers to apply them sequentially. Ideal for testing. (same idea as sampler above, but for schedulers)
|
||||||
|
|
||||||
## 12 - ♻ Loop Combos
|
## 12 - ♻ Loop Combos
|
||||||

|

|
||||||
@@ -153,6 +163,9 @@ Iterate over all available schedulers to apply them sequentially. Ideal for test
|
|||||||
Generate a loop from a list of my own custom combinations (scheduler+sampler), or select one combo manually.
|
Generate a loop from a list of my own custom combinations (scheduler+sampler), or select one combo manually.
|
||||||
Good for testing.
|
Good for testing.
|
||||||
|
|
||||||
|
Example of usage to see the differences between different combinations :
|
||||||
|

|
||||||
|
|
||||||
## 13/14 - 📏 + 🖼 Resize and Save Exact name ⚠️💣
|
## 13/14 - 📏 + 🖼 Resize and Save Exact name ⚠️💣
|
||||||

|

|
||||||
|
|
||||||
@@ -248,6 +261,7 @@ Need clean greenscreen ofc. (Can adjust threshold but very basic node.)
|
|||||||
|
|
||||||
**Description:**
|
**Description:**
|
||||||
Take a random line from an input text. (When using multiple "Write Text" nodes is annoying for example, you can use that and just copy/paste a list from outside.)
|
Take a random line from an input text. (When using multiple "Write Text" nodes is annoying for example, you can use that and just copy/paste a list from outside.)
|
||||||
|
You can change fixed/randomize for `control_after_generate` to have a different text each time you run the workflow. (or not)
|
||||||
|
|
||||||
## 27 - ♻ Loop (All Lines from input)
|
## 27 - ♻ Loop (All Lines from input)
|
||||||

|

|
||||||
@@ -363,14 +377,14 @@ You can connect this node to anything you want, above is an example with IMAGE.
|
|||||||
|
|
||||||
### 37 - 🎲🖼 Random Image
|
### 37 - 🎲🖼 Random Image
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
**Description:**
|
**Description:**
|
||||||
Just take a random image from a list of images.
|
Just take a random image from a list of images.
|
||||||
|
|
||||||
### 38 - ♻🖼 Loop (Images)
|
### 38 - ♻🖼 Loop (Images)
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
**Description:**
|
**Description:**
|
||||||
Loop over a list of images.
|
Loop over a list of images.
|
||||||
@@ -379,8 +393,22 @@ Above is an example of the loop images node sending them to an Ipadapter style t
|
|||||||
|
|
||||||
### 39 - ♻ Loop (✒ Write Text)
|
### 39 - ♻ Loop (✒ Write Text)
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
**Description:**
|
**Description:**
|
||||||
If you need a quick loop but you don't want something too complex with a loop node, you can use this combined write text + loop.
|
If you need a quick loop but you don't want something too complex with a loop node, you can use this combined write text + loop.
|
||||||
It will take the same special syntax as the write text node `{blue|red}`, but it will loop over ALL the possibilities instead of taking one at random.
|
It will take the same special syntax as the write text node `{blue|red}`, but it will loop over ALL the possibilities instead of taking one at random.
|
||||||
|
|
||||||
|
### 40 - 🎲 Random (Model+Clip+Vae) - aka Checkpoint / Model
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
**Description:**
|
||||||
|
Just take a trio at random from a load checkpoint node.
|
||||||
|
|
||||||
|
### 41 - ♻ Loop (Model+Clip+Vae) - aka Checkpoint / Model
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
**Description:**
|
||||||
|
Loop over all the trios from several checkpoint node.
|
||||||
83
__init__.py
83
__init__.py
@@ -46,6 +46,7 @@ from .loop_images import LoopImages
|
|||||||
from .random_image import RandomImage
|
from .random_image import RandomImage
|
||||||
from .loop_write_text import LoopWriteText
|
from .loop_write_text import LoopWriteText
|
||||||
# from .random_checkpoint import RandomCheckpoint
|
# from .random_checkpoint import RandomCheckpoint
|
||||||
|
from .loop_model_clip_vae import LoopModelClipVae
|
||||||
|
|
||||||
# from .pass_preview_image import PassPreviewImage
|
# from .pass_preview_image import PassPreviewImage
|
||||||
# from .check_black_image import CheckBlackImage
|
# from .check_black_image import CheckBlackImage
|
||||||
@@ -56,6 +57,7 @@ from .loop_write_text import LoopWriteText
|
|||||||
NODE_CLASS_MAPPINGS = {
|
NODE_CLASS_MAPPINGS = {
|
||||||
# "Bjornulf_CustomStringType": CustomStringType,
|
# "Bjornulf_CustomStringType": CustomStringType,
|
||||||
"Bjornulf_ollamaLoader": ollamaLoader,
|
"Bjornulf_ollamaLoader": ollamaLoader,
|
||||||
|
"Bjornulf_LoopModelClipVae": LoopModelClipVae,
|
||||||
# "Bjoenulf_RandomCheckpoint": RandomCheckpoint,
|
# "Bjoenulf_RandomCheckpoint": RandomCheckpoint,
|
||||||
"Bjornulf_LoopWriteText": LoopWriteText,
|
"Bjornulf_LoopWriteText": LoopWriteText,
|
||||||
"Bjornulf_LoopImages": LoopImages,
|
"Bjornulf_LoopImages": LoopImages,
|
||||||
@@ -110,52 +112,13 @@ NODE_CLASS_MAPPINGS = {
|
|||||||
|
|
||||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||||
# "Bjornulf_CustomStringType": "!!! CUSTOM STRING TYPE !!!",
|
# "Bjornulf_CustomStringType": "!!! CUSTOM STRING TYPE !!!",
|
||||||
"Bjornulf_ollamaLoader": "🦙 Ollama (Description)",
|
|
||||||
# "Bjoenulf_RandomCheckpoint": "🎲 Random Checkpoint",
|
|
||||||
"Bjornulf_LoopWriteText": "♻ Loop (✒ Write Text)",
|
|
||||||
"Bjornulf_LoopImages": "♻🖼 Loop (Images)",
|
|
||||||
"Bjornulf_RandomImage": "🎲🖼 Random Image",
|
|
||||||
# "Bjornulf_PassPreviewImage": "🖼⮕ Pass Preview Image",
|
|
||||||
"Bjornulf_PickInput": "⏸️🔍 Paused. Select input, Pick one",
|
|
||||||
"Bjornulf_PauseResume": "⏸️ Paused. Resume or Stop ?",
|
|
||||||
"Bjornulf_FreeVRAM": "🧹 Free VRAM hack",
|
|
||||||
"Bjornulf_CombineTextsByLines": "♻ Loop (All Lines from input 🔗 combine by lines)",
|
|
||||||
"Bjornulf_TextToSpeech": "🔊 TTS - Text to Speech",
|
|
||||||
"Bjornulf_CharacterDescriptionGenerator": "🧑📝 Character Description Generator",
|
|
||||||
"Bjornulf_ImageMaskCutter": "🖼✂ Cut Image with Mask",
|
|
||||||
"Bjornulf_LoadImageWithTransparency": "🖼 Load Image with Transparency ▢",
|
|
||||||
"Bjornulf_GreenScreenToTransparency": "🟩➜▢ Green Screen to Transparency",
|
|
||||||
# "Bjornulf_CheckBlackImage": "🔲 Check Black Image (Empty mask)",
|
|
||||||
"Bjornulf_SaveBjornulfLobeChat": "🖼💬 Save image for Bjornulf LobeChat",
|
|
||||||
"Bjornulf_TextToStringAndSeed": "🔢 Text with random Seed",
|
|
||||||
# "Bjornulf_ClearVRAM": "🧹 Clear VRAM",
|
|
||||||
"Bjornulf_RandomLineFromInput": "🎲 Random line from input",
|
|
||||||
"Bjornulf_ShowText": "👁 Show (Text)",
|
|
||||||
"Bjornulf_ShowInt": "👁 Show (Int)",
|
|
||||||
"Bjornulf_ShowFloat": "👁 Show (Float)",
|
|
||||||
"Bjornulf_CombineBackgroundOverlay": "🖼+🖼 Combine images (Background+Overlay alpha)",
|
|
||||||
"Bjornulf_GrayscaleTransform": "🖼➜🔲 Image to grayscale (black & white)",
|
|
||||||
"Bjornulf_RemoveTransparency": "▢➜⬛ Remove image Transparency (alpha)",
|
|
||||||
# "🔲➜⬛ Transparency to color",
|
|
||||||
"Bjornulf_ResizeImage": "📏 Resize Image",
|
|
||||||
"Bjornulf_SaveImagePath": "🖼 Save Image (exact path, exact name) ⚠️💣",
|
|
||||||
"Bjornulf_SaveImageToFolder": "🖼📁 Save Image(s) to a folder",
|
|
||||||
"Bjornulf_SaveTmpImage": "🖼 Save Image (tmp_api.png) ⚠️💣",
|
|
||||||
# "Bjornulf_SaveApiImage": "🖼 Save Image (./output/api_00001.png...)",
|
|
||||||
"Bjornulf_SaveText": "💾 Save Text", #Make SaveCharacter, SaveLocation, SaveCamera, SaveAction, SaveClothes, SaveEmotion...
|
|
||||||
"Bjornulf_LoadText": "📥 Load Text", #Make LoadCharacter, LoadLocation, LoadCamera, LoadAction, LoadClothes, LoadEmotion...
|
|
||||||
"Bjornulf_WriteText": "✒ Write Text",
|
"Bjornulf_WriteText": "✒ Write Text",
|
||||||
"Bjornulf_WriteTextInConsole": "✒🗔 Write Text (Console too) ",
|
"Bjornulf_WriteTextInConsole": "✒🗔 Write Text (Console too) ",
|
||||||
# "Bjornulf_WriteImageEnvironment": "✒ Write Image Environment",
|
"Bjornulf_LoopWriteText": "♻ Loop (✒ Write Text)",
|
||||||
# "Bjornulf_WriteImageCharacters": "✒ Write Image Characters",
|
"Bjornulf_LoopModelClipVae": "♻ Loop (Model+Clip+Vae)",
|
||||||
# "Bjornulf_WriteImageCharacter": "✒ Write Image Character",
|
"Bjornulf_LoopImages": "♻🖼 Loop (Images)",
|
||||||
# "Bjornulf_WriteImageAllInOne": "✒ Write Image All-in-one",
|
"Bjornulf_CombineTextsByLines": "♻ Loop (All Lines from input 🔗 combine by lines)",
|
||||||
"Bjornulf_CombineTexts": "🔗 Combine (Texts)",
|
|
||||||
"Bjornulf_LoopTexts": "♻ Loop (Texts)",
|
"Bjornulf_LoopTexts": "♻ Loop (Texts)",
|
||||||
"Bjornulf_RandomTexts": "🎲 Random (Texts)",
|
|
||||||
"Bjornulf_RandomModelClipVae": "🎲 Random (Model+Clip+Vae)",
|
|
||||||
"Bjornulf_imagesToVideo": "📹 images to video (FFmpeg)",
|
|
||||||
"Bjornulf_VideoPingPong": "📹 video PingPong",
|
|
||||||
"Bjornulf_LoopFloat": "♻ Loop (Float)",
|
"Bjornulf_LoopFloat": "♻ Loop (Float)",
|
||||||
"Bjornulf_LoopInteger": "♻ Loop (Integer)",
|
"Bjornulf_LoopInteger": "♻ Loop (Integer)",
|
||||||
"Bjornulf_LoopBasicBatch": "♻ Loop",
|
"Bjornulf_LoopBasicBatch": "♻ Loop",
|
||||||
@@ -163,6 +126,40 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
|||||||
"Bjornulf_LoopSamplers": "♻ Loop (All Samplers)",
|
"Bjornulf_LoopSamplers": "♻ Loop (All Samplers)",
|
||||||
"Bjornulf_LoopSchedulers": "♻ Loop (All Schedulers)",
|
"Bjornulf_LoopSchedulers": "♻ Loop (All Schedulers)",
|
||||||
"Bjornulf_LoopCombosSamplersSchedulers": "♻ Loop (My combos Sampler⚔Scheduler)",
|
"Bjornulf_LoopCombosSamplersSchedulers": "♻ Loop (My combos Sampler⚔Scheduler)",
|
||||||
|
"Bjornulf_RandomImage": "🎲🖼 Random Image",
|
||||||
|
"Bjornulf_RandomLineFromInput": "🎲 Random line from input",
|
||||||
|
"Bjornulf_RandomTexts": "🎲 Random (Texts)",
|
||||||
|
"Bjornulf_RandomModelClipVae": "🎲 Random (Model+Clip+Vae)",
|
||||||
|
# "Bjornulf_PassPreviewImage": "🖼⮕ Pass Preview Image",
|
||||||
|
"Bjornulf_CharacterDescriptionGenerator": "🧑📝 Character Description Generator",
|
||||||
|
"Bjornulf_GreenScreenToTransparency": "🟩➜▢ Green Screen to Transparency",
|
||||||
|
# "Bjornulf_CheckBlackImage": "🔲 Check Black Image (Empty mask)",
|
||||||
|
"Bjornulf_SaveBjornulfLobeChat": "🖼💬 Save image for Bjornulf LobeChat",
|
||||||
|
"Bjornulf_TextToStringAndSeed": "🔢 Text with random Seed",
|
||||||
|
# "Bjornulf_ClearVRAM": "🧹 Clear VRAM",
|
||||||
|
"Bjornulf_ShowText": "👁 Show (Text)",
|
||||||
|
"Bjornulf_ShowInt": "👁 Show (Int)",
|
||||||
|
"Bjornulf_ShowFloat": "👁 Show (Float)",
|
||||||
|
"Bjornulf_ImageMaskCutter": "🖼✂ Cut Image with Mask",
|
||||||
|
"Bjornulf_LoadImageWithTransparency": "🖼 Load Image with Transparency ▢",
|
||||||
|
"Bjornulf_CombineBackgroundOverlay": "🖼+🖼 Combine images (Background+Overlay alpha)",
|
||||||
|
"Bjornulf_GrayscaleTransform": "🖼➜🔲 Image to grayscale (black & white)",
|
||||||
|
"Bjornulf_RemoveTransparency": "▢➜⬛ Remove image Transparency (alpha)",
|
||||||
|
"Bjornulf_ResizeImage": "📏 Resize Image",
|
||||||
|
"Bjornulf_SaveImagePath": "🖼 Save Image (exact path, exact name) ⚠️💣",
|
||||||
|
"Bjornulf_SaveImageToFolder": "🖼📁 Save Image(s) to a folder",
|
||||||
|
"Bjornulf_SaveTmpImage": "🖼 Save Image (tmp_api.png) ⚠️💣",
|
||||||
|
# "Bjornulf_SaveApiImage": "🖼 Save Image (./output/api_00001.png...)",
|
||||||
|
"Bjornulf_SaveText": "💾 Save Text",
|
||||||
|
# "Bjornulf_LoadText": "📥 Load Text",
|
||||||
|
"Bjornulf_CombineTexts": "🔗 Combine (Texts)",
|
||||||
|
"Bjornulf_imagesToVideo": "📹 images to video (FFmpeg)",
|
||||||
|
"Bjornulf_VideoPingPong": "📹 video PingPong",
|
||||||
|
"Bjornulf_ollamaLoader": "🦙 Ollama (Description)",
|
||||||
|
"Bjornulf_FreeVRAM": "🧹 Free VRAM hack",
|
||||||
|
"Bjornulf_TextToSpeech": "🔊 TTS - Text to Speech",
|
||||||
|
"Bjornulf_PickInput": "⏸️🔍 Paused. Select input, Pick one",
|
||||||
|
"Bjornulf_PauseResume": "⏸️ Paused. Resume or Stop ?",
|
||||||
}
|
}
|
||||||
|
|
||||||
WEB_DIRECTORY = "./web"
|
WEB_DIRECTORY = "./web"
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ class CombineTextsByLines:
|
|||||||
RETURN_NAMES = tuple([f"line_{i+1}" for i in range(50)])
|
RETURN_NAMES = tuple([f"line_{i+1}" for i in range(50)])
|
||||||
FUNCTION = "extract_lines"
|
FUNCTION = "extract_lines"
|
||||||
OUTPUT_NODE = True
|
OUTPUT_NODE = True
|
||||||
CATEGORY = "text"
|
CATEGORY = "Bjornulf"
|
||||||
OUTPUT_IS_LIST = tuple([True] * 50) # Indicate that all outputs are lists
|
OUTPUT_IS_LIST = tuple([True] * 50) # Indicate that all outputs are lists
|
||||||
|
|
||||||
def extract_lines(self, number_of_inputs, number_of_lines, **kwargs):
|
def extract_lines(self, number_of_inputs, number_of_lines, **kwargs):
|
||||||
|
|||||||
31
loop_model_clip_vae.py
Normal file
31
loop_model_clip_vae.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
class LoopModelClipVae:
|
||||||
|
@classmethod
|
||||||
|
def INPUT_TYPES(cls):
|
||||||
|
return {
|
||||||
|
"required": {
|
||||||
|
"number_of_inputs": ("INT", {"default": 2, "min": 2, "max": 10, "step": 1}),
|
||||||
|
"model_1": ("MODEL", {"forceInput": True}),
|
||||||
|
"clip_1": ("CLIP", {"forceInput": True}),
|
||||||
|
"vae_1": ("VAE", {"forceInput": True}),
|
||||||
|
"model_2": ("MODEL", {"forceInput": True}),
|
||||||
|
"clip_2": ("CLIP", {"forceInput": True}),
|
||||||
|
"vae_2": ("VAE", {"forceInput": True}),
|
||||||
|
},
|
||||||
|
"hidden": {
|
||||||
|
**{f"model_{i}": ("MODEL", {"forceInput": True}) for i in range(3, 11)},
|
||||||
|
**{f"clip_{i}": ("CLIP", {"forceInput": True}) for i in range(3, 11)},
|
||||||
|
**{f"vae_{i}": ("VAE", {"forceInput": True}) for i in range(3, 11)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN_TYPES = ("MODEL", "CLIP", "VAE")
|
||||||
|
FUNCTION = "return_all"
|
||||||
|
OUTPUT_IS_LIST = (True, True, True)
|
||||||
|
CATEGORY = "Bjornulf"
|
||||||
|
|
||||||
|
def return_all(self, number_of_inputs, **kwargs):
|
||||||
|
models = [kwargs[f"model_{i}"] for i in range(1, number_of_inputs + 1) if f"model_{i}" in kwargs]
|
||||||
|
clips = [kwargs[f"clip_{i}"] for i in range(1, number_of_inputs + 1) if f"clip_{i}" in kwargs]
|
||||||
|
vaes = [kwargs[f"vae_{i}"] for i in range(1, number_of_inputs + 1) if f"vae_{i}" in kwargs]
|
||||||
|
|
||||||
|
return (models, clips, vaes)
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "bjornulf_custom_nodes"
|
name = "bjornulf_custom_nodes"
|
||||||
description = "Nodes: Ollama, Text to Speech, Combine Texts, Random Texts, Save image for Bjornulf LobeChat, Text with random Seed, Random line from input, Combine images, Image to grayscale (black & white), Remove image Transparency (alpha), Resize Image, ..."
|
description = "Nodes: Ollama, Text to Speech, Combine Texts, Random Texts, Save image for Bjornulf LobeChat, Text with random Seed, Random line from input, Combine images, Image to grayscale (black & white), Remove image Transparency (alpha), Resize Image, ..."
|
||||||
version = "0.26"
|
version = "0.28"
|
||||||
license = {file = "LICENSE"}
|
license = {file = "LICENSE"}
|
||||||
|
|
||||||
[project.urls]
|
[project.urls]
|
||||||
|
|||||||
@@ -7,21 +7,20 @@ class RandomTexts:
|
|||||||
"required": {
|
"required": {
|
||||||
"number_of_inputs": ("INT", {"default": 2, "min": 2, "max": 30, "step": 1}),
|
"number_of_inputs": ("INT", {"default": 2, "min": 2, "max": 30, "step": 1}),
|
||||||
"number_of_random": ("INT", {"default": 1, "min": 1, "max": 30, "step": 1}),
|
"number_of_random": ("INT", {"default": 1, "min": 1, "max": 30, "step": 1}),
|
||||||
# "text_1": ("STRING", {"forceInput": "True"}),
|
"seed": ("INT", {"default": 0}),
|
||||||
# "text_2": ("STRING", {"forceInput": "True"}),
|
|
||||||
"seed": ("INT", {"default": "1"}), #Used with control_after_generate,
|
|
||||||
},
|
},
|
||||||
"hidden": {
|
"hidden": {
|
||||||
**{f"text_{i}": ("STRING", {"forceInput": "True"}) for i in range(1, 31)}
|
**{f"text_{i}": ("STRING", {"forceInput": True}) for i in range(1, 31)}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RETURN_TYPES = ("STRING",)
|
RETURN_TYPES = ("STRING",)
|
||||||
FUNCTION = "random_texts"
|
FUNCTION = "random_texts"
|
||||||
OUTPUT_IS_LIST = (False,)
|
OUTPUT_IS_LIST = (True,)
|
||||||
CATEGORY = "Bjornulf"
|
CATEGORY = "Bjornulf"
|
||||||
|
|
||||||
def random_texts(self, number_of_inputs, number_of_random, **kwargs):
|
def random_texts(self, number_of_inputs, number_of_random, seed, **kwargs):
|
||||||
texts = [kwargs[f"text_{i}"] for i in range(1, number_of_inputs + 1) if f"text_{i}" in kwargs]
|
random.seed(seed)
|
||||||
|
texts = [kwargs[f"text_{i}"] for i in range(1, number_of_inputs + 1) if f"text_{i}" in kwargs and kwargs[f"text_{i}"]]
|
||||||
random_texts = random.sample(texts, min(number_of_random, len(texts)))
|
random_texts = random.sample(texts, min(number_of_random, len(texts)))
|
||||||
return (random_texts,)
|
return (random_texts,)
|
||||||
BIN
screenshots/example_combos.png
Normal file
BIN
screenshots/example_combos.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 700 KiB |
BIN
screenshots/example_loop_all_samplers.png
Normal file
BIN
screenshots/example_loop_all_samplers.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 976 KiB |
BIN
screenshots/loop_checkpoint.png
Normal file
BIN
screenshots/loop_checkpoint.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 306 KiB |
BIN
screenshots/loop_float_example.png
Normal file
BIN
screenshots/loop_float_example.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 864 KiB |
BIN
screenshots/loop_text_example.png
Normal file
BIN
screenshots/loop_text_example.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 579 KiB |
BIN
screenshots/random_checkpoint.png
Normal file
BIN
screenshots/random_checkpoint.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 256 KiB |
65
web/js/loop_model_clip_vae.js
Normal file
65
web/js/loop_model_clip_vae.js
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
import { app } from "../../../scripts/app.js";
|
||||||
|
|
||||||
|
app.registerExtension({
|
||||||
|
name: "Bjornulf.LoopModelClipVae",
|
||||||
|
async nodeCreated(node) {
|
||||||
|
if (node.comfyClass === "Bjornulf_LoopModelClipVae") {
|
||||||
|
const updateInputs = () => {
|
||||||
|
const numInputsWidget = node.widgets.find(w => w.name === "number_of_inputs");
|
||||||
|
if (!numInputsWidget) return;
|
||||||
|
|
||||||
|
const numInputs = numInputsWidget.value;
|
||||||
|
|
||||||
|
// Initialize node.inputs if it doesn't exist
|
||||||
|
if (!node.inputs) {
|
||||||
|
node.inputs = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter existing model, clip, and vae inputs
|
||||||
|
const existingModelInputs = node.inputs.filter(input => input.name.startsWith('model_'));
|
||||||
|
const existingClipInputs = node.inputs.filter(input => input.name.startsWith('clip_'));
|
||||||
|
const existingVaeInputs = node.inputs.filter(input => input.name.startsWith('vae_'));
|
||||||
|
|
||||||
|
// Determine if we need to add or remove inputs
|
||||||
|
if (existingModelInputs.length < numInputs || existingClipInputs.length < numInputs || existingVaeInputs.length < numInputs) {
|
||||||
|
// Add new model, clip, and vae inputs if not enough existing
|
||||||
|
for (let i = Math.max(existingModelInputs.length, existingClipInputs.length, existingVaeInputs.length) + 1; i <= numInputs; i++) {
|
||||||
|
const modelInputName = `model_${i}`;
|
||||||
|
const clipInputName = `clip_${i}`;
|
||||||
|
const vaeInputName = `vae_${i}`;
|
||||||
|
if (!node.inputs.find(input => input.name === modelInputName)) {
|
||||||
|
node.addInput(modelInputName, "MODEL");
|
||||||
|
}
|
||||||
|
if (!node.inputs.find(input => input.name === clipInputName)) {
|
||||||
|
node.addInput(clipInputName, "CLIP");
|
||||||
|
}
|
||||||
|
if (!node.inputs.find(input => input.name === vaeInputName)) {
|
||||||
|
node.addInput(vaeInputName, "VAE");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Remove excess model, clip, and vae inputs if too many
|
||||||
|
node.inputs = node.inputs.filter(input =>
|
||||||
|
(!input.name.startsWith('model_') && !input.name.startsWith('clip_') && !input.name.startsWith('vae_')) ||
|
||||||
|
(parseInt(input.name.split('_')[1]) <= numInputs)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
node.setSize(node.computeSize());
|
||||||
|
};
|
||||||
|
|
||||||
|
// Move number_of_inputs to the top initially
|
||||||
|
const numInputsWidget = node.widgets.find(w => w.name === "number_of_inputs");
|
||||||
|
if (numInputsWidget) {
|
||||||
|
node.widgets = [numInputsWidget, ...node.widgets.filter(w => w !== numInputsWidget)];
|
||||||
|
numInputsWidget.callback = () => {
|
||||||
|
updateInputs();
|
||||||
|
app.graph.setDirtyCanvas(true);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delay the initial update to ensure node is fully initialized
|
||||||
|
setTimeout(updateInputs, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user