diff --git a/README.md b/README.md index 1439b91..4fee0c5 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# 🔗 Comfyui : Bjornulf_custom_nodes v0.15 🔗 +# 🔗 Comfyui : Bjornulf_custom_nodes v0.16 🔗 # Dependencies @@ -25,6 +25,7 @@ - **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.15**: Add two new nodes: TTS - Text to Speech and Character Description Generator +- **v0.16**: Big changes on Character Description Generator # 📝 Nodes descriptions @@ -245,7 +246,7 @@ The default `Load Image` node will not load the transparency. Cut an image from a mask. ## 31 - 🔊 TTS - Text to Speech -![Cut image](screenshots/tts.png) +![TTS](screenshots/tts.png) **Description:** 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 ) and voice samples are good, you can use this node to generate speech from text. ### 32 - 🧑📝 Character Description Generator -![Cut image](screenshots/characters.png) +![characters](screenshots/characters.png) +![characters](screenshots/characters2.png) **Description:** 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. -❗ For now it's very basic node, a lot of things are going to be added. \ No newline at end of file +❗ 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. \ No newline at end of file diff --git a/character_description.py b/character_description.py index 983d765..6e0316d 100644 --- a/character_description.py +++ b/character_description.py @@ -27,96 +27,79 @@ class CharacterDescriptionGenerator: def generate_descriptions(self, character_file): current_dir = os.path.dirname(os.path.realpath(__file__)) file_path = os.path.join(current_dir, "characters", character_file) - + if not os.path.exists(file_path): return (f"Error: File {character_file} not found.", "") - + try: with open(file_path, 'r') as file: data = json.load(file) - + name = data.get('name', 'Unknown') + nationality = data.get('nationality', 'Unknown') age = data.get('age', 'Unknown') gender = data.get('gender', 'Unknown').lower() height = data.get('height', 'Unknown') weight = data.get('weight', 'Unknown') - + body_type = data.get('body_type', {}) face = data.get('face', {}) eyes = face.get('eyes', {}) - hair = face.get('hair', {}) - body_type = face.get('body_type', {}) + hair = data.get('hair', {}) - # Define pronouns based on gender + pronouns = { + 'subject': 'They', + 'object': 'them', + 'possessive': 'their' + } if gender in ['female', 'f']: - pronouns = { - 'subject': 'She', - 'object': 'her', - 'possessive': 'her' - } + pronouns = {'subject': 'She', 'object': 'her', 'possessive': 'her'} elif gender in ['male', 'm']: - pronouns = { - 'subject': 'He', - 'object': 'him', - 'possessive': 'his' - } - else: - pronouns = { - 'subject': 'They', - 'object': 'them', - 'possessive': 'their' - } + pronouns = {'subject': 'He', 'object': 'him', 'possessive': 'his'} - # Generate sentences description - sentences = f"{name} is a {age}-year-old {gender} standing {height} tall and weighing {weight}. " - - 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." + body_desc = f"{body_type.get('build', '')} and {body_type.get('figure', '')}" + 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" + 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 = [ f"{age} years old", - gender, + f"{nationality}", + f"{gender}", f"{height} tall", - f"{weight} weight", - face.get('shape', 'unknown').lower() + " face", - face.get('complexion', 'unknown').lower() + " complexion", - eyes.get('color', 'unknown').lower() + " eyes", - eyes.get('shape', 'unknown').lower() + " eyes", - eyes.get('feature', 'unknown').lower() + " eyelashes", - face.get('nose', 'unknown').lower() + " nose", - face.get('lips', 'unknown').lower() + " lips", - face.get('cheekbones', 'unknown').lower() + " cheekbones", - face.get('jawline', 'unknown').lower() + " jawline", - hair.get('color', 'unknown') + " hair", - hair.get('length', 'unknown').lower() + " hair", - hair.get('texture', 'unknown').lower() + " hair", - hair.get('style', 'unknown').lower() + " hairstyle", - body_type.get('build', 'unknown').lower() + " build", - body_type.get('figure', 'unknown').lower() + " figure", - body_type.get('shoulders', 'unknown').lower() + " shoulders", - body_type.get('waist', 'unknown').lower() + " waist", - body_type.get('hips', 'unknown').lower() + " hips" + f"{weight}", + f"{body_type.get('build', '')} build", + f"{body_type.get('figure', '')} figure", + f"{body_type.get('shoulders', '')} shoulders", + f"{body_type.get('waist', '')} waist", + f"{body_type.get('hips', '')} hips", + f"{eyes.get('color', '')} eyes", + f"{eyes.get('shape', '')} eyes", + f"{eyes.get('feature', '')} eyes", + f"{hair.get('length', '')} hair", + f"{hair.get('color', '')} hair", + f"{hair.get('texture', '')} hair", + f"{hair.get('style', '')}", + f"{face.get('complexion', '')} complexion", + f"{face.get('shape', '')} face", + f"{face.get('nose', '')} nose", + f"{face.get('lips', '')} lips", + f"{face.get('cheekbones', '')} cheekbones", + f"{face.get('jawline', '')} jawline" ] words = ", ".join(words_list) - + return (sentences, words, character_file.replace('.json', '')) - + except Exception as e: - return (f"Error processing {character_file}: {str(e)}", "") \ No newline at end of file + return (f"Error processing {character_file}: {str(e)}", "") diff --git a/pyproject.toml b/pyproject.toml index abe4c0e..e9978e2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] 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, ..." -version = "0.15" +version = "0.16" license = {file = "LICENSE"} [project.urls] diff --git a/screenshots/characters.png b/screenshots/characters.png index 2c29bdb..f5b6fd9 100644 Binary files a/screenshots/characters.png and b/screenshots/characters.png differ diff --git a/screenshots/characters2.png b/screenshots/characters2.png new file mode 100644 index 0000000..c953bbe Binary files /dev/null and b/screenshots/characters2.png differ