This commit is contained in:
justumen
2024-09-09 13:42:58 +02:00
parent 1d3366ca7b
commit c7faf321ff
5 changed files with 59 additions and 73 deletions

View File

@@ -1,4 +1,4 @@
# 🔗 Comfyui : Bjornulf_custom_nodes v0.15 🔗 # 🔗 Comfyui : Bjornulf_custom_nodes v0.16 🔗
# Dependencies # Dependencies
@@ -25,6 +25,7 @@
- **v0.13**: Add a new node: Load image with transparency (alpha) - Load an image with transparency. - **v0.13**: Add a new node: Load image with transparency (alpha) - Load an image with transparency.
- **v0.14**: Add a new node: Cut image from a mask - **v0.14**: Add a new node: Cut image from a mask
- **v0.15**: Add two new nodes: TTS - Text to Speech and Character Description Generator - **v0.15**: Add two new nodes: TTS - Text to Speech and Character Description Generator
- **v0.16**: Big changes on Character Description Generator
# 📝 Nodes descriptions # 📝 Nodes descriptions
@@ -245,7 +246,7 @@ The default `Load Image` node will not load the transparency.
Cut an image from a mask. Cut an image from a mask.
## 31 - 🔊 TTS - Text to Speech ## 31 - 🔊 TTS - Text to Speech
![Cut image](screenshots/tts.png) ![TTS](screenshots/tts.png)
**Description:** **Description:**
Use my TTS server to generate speech from text. Use my TTS server to generate speech from text.
@@ -255,9 +256,11 @@ That link must must be a link to the folder where you store the voice samples yo
If my TTS server is running on port 8020 (You can test in browser with the link <http://localhost:8020/tts_stream?language=en&speaker_wav=default&text=Hello>) and voice samples are good, you can use this node to generate speech from text. If my TTS server is running on port 8020 (You can test in browser with the link <http://localhost:8020/tts_stream?language=en&speaker_wav=default&text=Hello>) and voice samples are good, you can use this node to generate speech from text.
### 32 - 🧑📝 Character Description Generator ### 32 - 🧑📝 Character Description Generator
![Cut image](screenshots/characters.png) ![characters](screenshots/characters.png)
![characters](screenshots/characters2.png)
**Description:** **Description:**
Generate a character description based on a json file in the folder `characters` : `ComfyUI/custom_nodes/Bjornulf_custom_nodes/characters` Generate a character description based on a json file in the folder `characters` : `ComfyUI/custom_nodes/Bjornulf_custom_nodes/characters`
Make your own json file with your own characters, and use this node to generate a description. Make your own json file with your own characters, and use this node to generate a description.
❗ For now it's very basic node, a lot of things are going to be added. ❗ For now it's very basic node, a lot of things are going to be added and changed !!!
Some details are unusable for some checkpoints, very much a work in progress, the json structure isn't set in stone either.

View File

@@ -27,96 +27,79 @@ class CharacterDescriptionGenerator:
def generate_descriptions(self, character_file): def generate_descriptions(self, character_file):
current_dir = os.path.dirname(os.path.realpath(__file__)) current_dir = os.path.dirname(os.path.realpath(__file__))
file_path = os.path.join(current_dir, "characters", character_file) file_path = os.path.join(current_dir, "characters", character_file)
if not os.path.exists(file_path): if not os.path.exists(file_path):
return (f"Error: File {character_file} not found.", "") return (f"Error: File {character_file} not found.", "")
try: try:
with open(file_path, 'r') as file: with open(file_path, 'r') as file:
data = json.load(file) data = json.load(file)
name = data.get('name', 'Unknown') name = data.get('name', 'Unknown')
nationality = data.get('nationality', 'Unknown')
age = data.get('age', 'Unknown') age = data.get('age', 'Unknown')
gender = data.get('gender', 'Unknown').lower() gender = data.get('gender', 'Unknown').lower()
height = data.get('height', 'Unknown') height = data.get('height', 'Unknown')
weight = data.get('weight', 'Unknown') weight = data.get('weight', 'Unknown')
body_type = data.get('body_type', {})
face = data.get('face', {}) face = data.get('face', {})
eyes = face.get('eyes', {}) eyes = face.get('eyes', {})
hair = face.get('hair', {}) hair = data.get('hair', {})
body_type = face.get('body_type', {})
# Define pronouns based on gender pronouns = {
'subject': 'They',
'object': 'them',
'possessive': 'their'
}
if gender in ['female', 'f']: if gender in ['female', 'f']:
pronouns = { pronouns = {'subject': 'She', 'object': 'her', 'possessive': 'her'}
'subject': 'She',
'object': 'her',
'possessive': 'her'
}
elif gender in ['male', 'm']: elif gender in ['male', 'm']:
pronouns = { pronouns = {'subject': 'He', 'object': 'him', 'possessive': 'his'}
'subject': 'He',
'object': 'him',
'possessive': 'his'
}
else:
pronouns = {
'subject': 'They',
'object': 'them',
'possessive': 'their'
}
# Generate sentences description body_desc = f"{body_type.get('build', '')} and {body_type.get('figure', '')}"
sentences = f"{name} is a {age}-year-old {gender} standing {height} tall and weighing {weight}. " eyes_desc = f"{eyes.get('color', '')} {eyes.get('shape', '')} eyes that appear {eyes.get('feature', '')}"
hair_desc = f"{hair.get('length', '')} {hair.get('color', '')} {hair.get('texture', '')} hair"
if face:
sentences += f"{pronouns['subject']} has an {face.get('shape', 'unknown').lower()} face with a {face.get('complexion', 'unknown').lower()} complexion. "
if eyes:
sentences += f"{pronouns['possessive'].capitalize()} {eyes.get('color', 'unknown').lower()} eyes are {eyes.get('shape', 'unknown').lower()} "
sentences += f"with {eyes.get('feature', 'unknown').lower()}. "
sentences += f"{pronouns['possessive'].capitalize()} nose is {face.get('nose', 'unknown').lower()}, and {pronouns['possessive']} lips are {face.get('lips', 'unknown').lower()}. "
sentences += f"{pronouns['subject']} has {face.get('cheekbones', 'unknown').lower()} cheekbones and a {face.get('jawline', 'unknown').lower()} jawline. "
if hair:
sentences += f"{name}'s {hair.get('color', 'unknown')} hair is {hair.get('length', 'unknown').lower()} and {hair.get('texture', 'unknown').lower()}, "
sentences += f"{hair.get('style', 'unknown').lower()}. "
if body_type:
sentences += f"{pronouns['subject']} has a {body_type.get('build', 'unknown').lower()} body type with a {body_type.get('figure', 'unknown').lower()} figure, "
sentences += f"{body_type.get('shoulders', 'unknown').lower()} shoulders, a {body_type.get('waist', 'unknown').lower()} waist, "
sentences += f"and {body_type.get('hips', 'unknown').lower()} hips."
sentences = (
f"{name} is a {age}-year-old {nationality} {gender.lower()}. "
f"{pronouns['subject']} stands at {height} and weighs {weight}. "
f"{pronouns['subject']} has a {body_desc} build, with {body_type.get('shoulders', '')} shoulders, "
f"a {body_type.get('waist', '')} waist, and {body_type.get('hips', '')} hips. "
f"{pronouns['possessive'].capitalize()} face is characterized by {eyes_desc}, complemented by {hair_desc} "
f"that {pronouns['subject'].lower()} usually styles {hair.get('style', '')}. "
f"{name}'s complexion is {face.get('complexion', '')}, with a {face.get('shape', '')} face shape, "
f"a {face.get('nose', '')} nose, {face.get('lips', '')} lips, {face.get('cheekbones', '')} cheekbones, "
f"and a {face.get('jawline', '')} jawline."
)
# Generate words description
words_list = [ words_list = [
f"{age} years old", f"{age} years old",
gender, f"{nationality}",
f"{gender}",
f"{height} tall", f"{height} tall",
f"{weight} weight", f"{weight}",
face.get('shape', 'unknown').lower() + " face", f"{body_type.get('build', '')} build",
face.get('complexion', 'unknown').lower() + " complexion", f"{body_type.get('figure', '')} figure",
eyes.get('color', 'unknown').lower() + " eyes", f"{body_type.get('shoulders', '')} shoulders",
eyes.get('shape', 'unknown').lower() + " eyes", f"{body_type.get('waist', '')} waist",
eyes.get('feature', 'unknown').lower() + " eyelashes", f"{body_type.get('hips', '')} hips",
face.get('nose', 'unknown').lower() + " nose", f"{eyes.get('color', '')} eyes",
face.get('lips', 'unknown').lower() + " lips", f"{eyes.get('shape', '')} eyes",
face.get('cheekbones', 'unknown').lower() + " cheekbones", f"{eyes.get('feature', '')} eyes",
face.get('jawline', 'unknown').lower() + " jawline", f"{hair.get('length', '')} hair",
hair.get('color', 'unknown') + " hair", f"{hair.get('color', '')} hair",
hair.get('length', 'unknown').lower() + " hair", f"{hair.get('texture', '')} hair",
hair.get('texture', 'unknown').lower() + " hair", f"{hair.get('style', '')}",
hair.get('style', 'unknown').lower() + " hairstyle", f"{face.get('complexion', '')} complexion",
body_type.get('build', 'unknown').lower() + " build", f"{face.get('shape', '')} face",
body_type.get('figure', 'unknown').lower() + " figure", f"{face.get('nose', '')} nose",
body_type.get('shoulders', 'unknown').lower() + " shoulders", f"{face.get('lips', '')} lips",
body_type.get('waist', 'unknown').lower() + " waist", f"{face.get('cheekbones', '')} cheekbones",
body_type.get('hips', 'unknown').lower() + " hips" f"{face.get('jawline', '')} jawline"
] ]
words = ", ".join(words_list) words = ", ".join(words_list)
return (sentences, words, character_file.replace('.json', '')) return (sentences, words, character_file.replace('.json', ''))
except Exception as e: except Exception as e:
return (f"Error processing {character_file}: {str(e)}", "") return (f"Error processing {character_file}: {str(e)}", "")

View File

@@ -1,7 +1,7 @@
[project] [project]
name = "bjornulf_custom_nodes" name = "bjornulf_custom_nodes"
description = "Nodes: Ollama, Text to Speech, Save image for Bjornulf LobeChat, Text with random Seed, Random line from input, Combine images (Background+Overlay alpha), Image to grayscale (black & white), Remove image Transparency (alpha), Resize Image, ..." description = "Nodes: Ollama, Text to Speech, Save image for Bjornulf LobeChat, Text with random Seed, Random line from input, Combine images (Background+Overlay alpha), Image to grayscale (black & white), Remove image Transparency (alpha), Resize Image, ..."
version = "0.15" version = "0.16"
license = {file = "LICENSE"} license = {file = "LICENSE"}
[project.urls] [project.urls]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB

After

Width:  |  Height:  |  Size: 166 KiB

BIN
screenshots/characters2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 KiB