11 Commits
Author SHA1 Message Date
OpalSky 86fe266e48 Delete __pycache__ directory 2024-10-27 14:13:39 -06:00
Opalsky-ai dbdcfcbf55 Updated repository structure, removed __pycache__, and improved .gitignore 2024-10-27 14:03:41 -06:00
Opalsky-ai 56374c150c Removed __pycache__ and updated .gitignore 2024-10-27 13:57:22 -06:00
OpalSky a92a2a952d README.md 2024-10-25 01:46:15 -06:00
OpalSky 85e7bbdb1a Delete Readme.md 2024-10-25 01:45:38 -06:00
OpalSky 23b0c9bcc1 README.md 2024-10-25 01:45:12 -06:00
OpalSky 9d7abfd3ad README.md 2024-10-25 01:42:28 -06:00
Opalsky-ai efa5d489e3 Staging local changes 2024-10-25 01:30:59 -06:00
Opalsky-ai f28ce8f32f Staging Local Changes.
Merge branch 'main' of https://github.com/OpalSky-AI/OpalSky_Nodes
2024-10-25 01:26:42 -06:00
Opalsky-ai 3082ab2e34 Staging local changes 2024-10-25 01:26:17 -06:00
OpalSky 0350718d73 Initial commit 2024-10-25 01:17:47 -06:00
12 changed files with 573 additions and 200 deletions
+2
View File
@@ -0,0 +1,2 @@
__pycache__/
*.pyc
+16
View File
@@ -0,0 +1,16 @@
# OpalSky_Nodes
# String Switch OpalSky
A custom node for ComfyUI that allows users to concatenate strings from predefined styles and custom inputs.
## Features
- Select predefined styles like Lighting and Atmosphere, Artistic Medium and Texture, etc.
- Toggle individual strings on/off for concatenation.
- Output dynamically created based on the user's selections.
## Installation
1. Clone the repository:
```bash
git clone https://github.com/OpalSky-AI/OpalSky_Nodes
-62
View File
@@ -1,62 +0,0 @@
Node Name: StringSwitch_OpalSky
Description:
The StringSwitch_OpalSky node concatenates up to five strings based on corresponding boolean switches. When a switch is turned on (set to True), the associated string is included in the output. The resulting strings are concatenated into a single string, separated by commas and spaces.
This node is useful for scenarios where you want to create dynamic text outputs based on selected conditions, such as generating prompt strings for image generation or combining text for other purposes.
Inputs:
string_1 to string_5 (STRING): These are text inputs where you can input any string. Each string is paired with a boolean switch that determines whether it will be included in the concatenated result.
switch_1 to switch_5 (BOOLEAN): Boolean switches that correspond to the strings above. When a switch is set to True, the respective string will be included in the output. If a switch is set to False, the associated string will be ignored.
Outputs:
concatenated_string (STRING): The concatenated result of all selected strings. Only strings whose corresponding switches are turned on (True) will appear in the result, separated by a comma and a space (, ).
Example Usage:
Input:
string_1 = "dark cinematic lighting"
string_2 = "photo realistic"
string_3 = "high resolution"
string_4 = ""
string_5 = "movie poster"
switch_1 = True
switch_2 = True
switch_3 = False
switch_4 = False
switch_5 = True
Output:
concatenated_string = "dark cinematic lighting, photo realistic, movie poster"
In this example, string_1, string_2, and string_5 are concatenated because their corresponding switches are turned on (True). string_3 and string_4 are not included because either the string is empty or the switch is set to False.
Edge Cases:
All Switches Off:
If all the switches are set to False, the output will be an empty string ("").
Empty Strings:
If a string input is empty but the switch is turned on, the empty string will not be included in the output. The concatenation only includes non-empty strings.
Mixed Empty Strings and Switches:
You can input a combination of filled and empty strings, with the corresponding switches determining what gets included in the final output.
How to Use in ComfyUI:
Add the StringSwitchOpalSky node from the node library (found under custom nodes).
Enter the desired text strings into the input fields.
Toggle the boolean switches to include or exclude the respective strings.
The concatenated string output will be available at the concatenated_string output, which can be connected to other nodes that require a string input.
Where to Save the Documentation:
The documentation should be stored in a location where it can be easily accessed by users, such as:
In the Node Directory:
You can save the documentation in a markdown file called README.md or DOCUMENTATION.md within the same folder where the node is stored (e.g., custom_nodes/OpalSky_Nodes/README.md).
In a Wiki or Documentation System:
If you’re distributing your node on platforms like GitHub, Civitai, or any other open-source node repository, you can include the documentation in the repository's main README.md file or in a separate docs/ folder.
As Part of ComfyUI's Node Documentation:
If ComfyUI has an integrated documentation system (like tooltips or an in-app help menu), you could submit the documentation to be included there.
For Personal Use:
If this node is only for your personal use, consider keeping the documentation in your own documentation folder alongside other custom nodes or projects.
This documentation provides clear instructions on how to use the node and covers most scenarios users might encounter. You can expand or modify it as needed based on additional features or user feedback.
-79
View File
@@ -1,79 +0,0 @@
{
"Lighting and Atmosphere": {
"categories": ["none", "Volumetric", "Cinematic", "Low-key", "High-key", "Natural Light", "Artificial Light", "Dynamic Lighting Effects", "Emotive Lighting", "Environmental Lighting"],
"tags": {
"none": "",
"Volumetric": "dramatic lighting, volumetric, moody",
"Cinematic": "cinematic lighting, vibrant, high contrast",
"Low-key": "low-key, moody, bokeh",
"High-key": "high-key, vibrant, high contrast",
"Natural Light": "natural lighting, bokeh, soft lighting",
"Artificial Light": "artificial lighting, vibrant, bokeh",
"Dynamic Lighting Effects": "long exposure, motion blur, streaks of light",
"Emotive Lighting": "warm lighting, cozy, sunset tones, cold lighting, blue hour",
"Environmental Lighting": "underwater lighting, forest sunlight, urban night lighting"
}
},
"Artistic Medium and Texture": {
"categories": ["none", "3D Render", "Claymation", "Low-poly", "Pixel Art", "Origami", "Analog Film", "Classic vs Digital Medium", "Mixed Media", "Material-Based Textures", "Surface Techniques"],
"tags": {
"none": "",
"3D Render": "octane render, 3D render, realistic",
"Claymation": "clay art, stop motion, organic texture",
"Low-poly": "low-poly, geometric, simple shapes",
"Pixel Art": "pixel art, 8-bit, retro",
"Origami": "pleated paper, folded paper, geometric texture",
"Analog Film": "film grain, soft focus, vintage look",
"Classic vs Digital Medium": "pencil sketch, digital glitch, VR-inspired",
"Mixed Media": "collage, graphite with 3D effects, acrylic paint textures",
"Material-Based Textures": "metallic, fabric, wood grain, glass",
"Surface Techniques": "aged paper, weathered wood, polished metal, cracked paint"
}
},
"Cultural and Genre Influences": {
"categories": ["none", "Cyberpunk", "Fantasy", "Anime", "Comic", "Neonpunk", "Retro", "Historical vs Contemporary", "Regional Influences", "Fantasy and Sci-Fi Subgenres"],
"tags": {
"none": "",
"Cyberpunk": "vaporwave, neon, dystopian",
"Fantasy": "celestial, epic, magical realism",
"Anime": "studio anime, cel-shaded, vibrant colors",
"Comic": "graphic novel art, black and white, halftone texture",
"Neonpunk": "neon, futuristic, high contrast",
"Retro": "vintage, 80s, pastel colors",
"Historical vs Contemporary": "Renaissance, modernist, Baroque, retro-futurism",
"Regional Influences": "East Asian ink painting, American comic style, African tribal art",
"Fantasy and Sci-Fi Subgenres": "high fantasy, urban fantasy, space opera, post-apocalyptic"
}
},
"Composition and Style Structure": {
"categories": ["none", "Isometric", "Cinematic", "Minimalist", "Vignette", "Line Art", "Centered Composition", "Depth and Focus", "Symmetry and Asymmetry", "Framing Techniques", "Abstract vs Representational"],
"tags": {
"none": "",
"Isometric": "isometric, geometric shapes, balanced",
"Cinematic": "shallow depth of field, wide-angle, dramatic composition",
"Minimalist": "minimalist, clean lines, negative space",
"Vignette": "vignette, soft edges, dramatic focus",
"Line Art": "line art, monochrome, black and white",
"Centered Composition": "centered composition, balanced, symmetry",
"Depth and Focus": "deep depth of field, shallow depth of field, bokeh background",
"Symmetry and Asymmetry": "perfect symmetry, rule of thirds, chaotic composition",
"Framing Techniques": "close-up, wide shot, over-the-shoulder, dutch angle",
"Abstract vs Representational": "cubist, surrealist, portrait, landscape"
}
},
"Photography and Realism": {
"categories": ["none", "Analog Film", "Photographic", "Cinematic Still", "35mm", "DSLR", "Camera Techniques", "Resolution and Clarity", "Film Style and Vintage Effects", "Environmental Realism"],
"tags": {
"none": "",
"Analog Film": "Kodachrome, grainy, vintage",
"Photographic": "highly detailed, realistic, 4k",
"Cinematic Still": "cinemascope, dramatic, cinematic look",
"35mm": "grainy, desaturated, soft focus",
"DSLR": "sharp focus, vibrant colors, realistic",
"Camera Techniques": "fisheye, macro, telephoto, panoramic",
"Resolution and Clarity": "low-fi aesthetic, super HD, HDR",
"Film Style and Vintage Effects": "black and white, sepia, Polaroid",
"Environmental Realism": "rain effect, foggy atmosphere, autumn scene"
}
}
}
+106
View File
@@ -0,0 +1,106 @@
{
"Lighting and Atmosphere": {
"categories": ["none", "Volumetric", "Cinematic: Epic", "Cinematic: Soft Cinematic", "Cinematic: Vintage", "Cinematic: Neo-noir", "Low-key", "High-key", "Natural Light: Golden Hour", "Natural Light: Soft Daylight", "Artificial Light: Fluorescent", "Artificial Light: Neon", "Backlighting"],
"tags": {
"none": "",
"Volumetric": "dramatic lighting, volumetric, moody, fog, light rays, ethereal glow",
"Cinematic: Epic": "high contrast, dramatic shadows, vibrant, sweeping light, filmic",
"Cinematic: Soft Cinematic": "subtle contrast, warm tones, natural, soft shadows",
"Cinematic: Vintage": "film grain, muted tones, nostalgic, sepia, retro look",
"Cinematic: Neo-noir": "dark shadows, high contrast, moody, urban, gritty",
"Low-key": "dark, moody, bokeh, deep shadows, low saturation",
"High-key": "bright, airy, high exposure, vibrant whites, soft shadows",
"Natural Light: Golden Hour": "soft warmth, golden hues, sunrise/sunset, gentle light",
"Natural Light: Soft Daylight": "outdoor lighting, diffused light, natural shadows, clear",
"Artificial Light: Fluorescent": "bright, cool tones, indoor lighting, sterile, vibrant",
"Artificial Light: Neon": "vibrant colors, neon lights, urban glow, cyberpunk vibe",
"Backlighting": "soft silhouette, rim light, dramatic shadows, ethereal glow"
}
},
"Artistic Medium and Texture": {
"categories": ["none", "Traditional Painting: Oil", "Traditional Painting: Watercolor", "Traditional Painting: Acrylic", "Digital Painting: Concept Art", "Digital Painting: Hyperrealistic", "Cel Animation: 90s Disney", "Cel Animation: Anime", "Graffiti", "Low-Poly", "Ink: Black and White", "Ink: Wash", "Mosaic", "Origami", "Claymation", "Pixel Art", "3D Render: Pixar Style", "3D Render: Realistic"],
"tags": {
"none": "",
"Traditional Painting: Oil": "rich texture, visible brush strokes, oil on canvas, fine art",
"Traditional Painting: Watercolor": "soft tones, paper grain, delicate washes, natural bleed",
"Traditional Painting: Acrylic": "bright colors, solid textures, layered brush strokes",
"Digital Painting: Concept Art": "vivid colors, smooth gradients, fantasy, sci-fi",
"Digital Painting: Hyperrealistic": "photo-realism, detailed, polished, high contrast",
"Cel Animation: 90s Disney": "hand-drawn, vibrant colors, clean lines, expressive",
"Cel Animation: Anime": "vibrant colors, cel shading, bold outlines, iconic anime",
"Graffiti": "urban style, spray paint, tags, street art, gritty texture",
"Low-Poly": "geometric, retro game style, blocky, simple textures",
"Ink: Black and White": "monochrome, cross-hatching, clean lines, bold contrast",
"Ink: Wash": "soft, watery, gentle gradations, classic comic look",
"Mosaic": "tiles, fragmented design, color blocks, abstract",
"Origami": "folded paper, geometric shapes, simple, clean lines",
"Claymation": "handmade texture, stop-motion, tangible details",
"Pixel Art": "8-bit style, retro, pixelated, low resolution, nostalgic",
"3D Render: Pixar Style": "smooth textures, vivid colors, stylized, playful characters",
"3D Render: Realistic": "high detail, octane render, photorealistic, complex textures"
}
},
"Cultural and Genre Influences": {
"categories": ["none", "Cyberpunk: Vaporwave", "Cyberpunk: Dystopian", "Fantasy: High Fantasy", "Fantasy: Dark Fantasy", "Fantasy: Elemental", "Sci-Fi: Space Opera", "Sci-Fi: Alien Worlds", "Anime: Shonen", "Anime: Shojo", "Anime: Mecha", "Anime: Cyber Anime", "Comic: Western", "Comic: Manga", "Retro: 80s", "Retro: 90s", "Retro: Pop Art", "Steampunk", "Gothic Horror", "Dieselpunk", "Lovecraftian", "Historical: Victorian", "Historical: Medieval"],
"tags": {
"none": "",
"Cyberpunk: Vaporwave": "neon lights, high-tech, futuristic, bold colors, surreal",
"Cyberpunk: Dystopian": "dark atmosphere, gritty, neon signs, urban, high contrast",
"Fantasy: High Fantasy": "celestial, epic, magical realism, mythical creatures, enchanted",
"Fantasy: Dark Fantasy": "grim, eerie, dark atmosphere, ominous, twisted landscapes",
"Fantasy: Elemental": "elemental powers, fire, water, earth, air, mystical forces",
"Sci-Fi: Space Opera": "galactic, advanced tech, spaceships, dramatic landscapes",
"Sci-Fi: Alien Worlds": "extraterrestrial, surreal landscapes, bioluminescent",
"Anime: Shonen": "action-packed, heroic, dynamic poses, bright colors",
"Anime: Shojo": "romantic, pastel colors, soft light, feminine, dreamlike",
"Anime: Mecha": "giant robots, futuristic, mechanical, sci-fi, strong lines",
"Anime: Cyber Anime": "neon glow, dark futuristic, cybernetic, cityscapes",
"Comic: Western": "bold lines, vibrant colors, action scenes, dynamic",
"Comic: Manga": "monochrome, expressive, detailed line work, emotional",
"Retro: 80s": "neon colors, geometric, pop culture, vintage vibe",
"Retro: 90s": "grunge, pastel, nostalgic, dynamic style",
"Retro: Pop Art": "bold outlines, halftone, bright colors, iconic look",
"Steampunk": "brass, mechanical, Victorian influence, steam-powered",
"Gothic Horror": "dark, eerie, shadows, gothic architecture, haunted",
"Dieselpunk": "industrial, WWII-inspired, gritty, mechanical",
"Lovecraftian": "eldritch, cosmic horror, surreal, twisted creatures",
"Historical: Victorian": "ornate, muted tones, refined, historical charm",
"Historical: Medieval": "knights, castles, earthy tones, old-world style"
}
},
"Composition and Style Structure": {
"categories": ["none", "Cinematic: Dramatic", "Cinematic: Shallow Depth", "Minimalist", "Isometric", "Vignette", "Line Art", "Abstract", "Symmetrical", "Chaos", "Centered Composition", "Dynamic Composition"],
"tags": {
"none": "",
"Cinematic: Dramatic": "high contrast, dark shadows, strong focus on subject",
"Cinematic: Shallow Depth": "blurred background, sharp foreground, close-up",
"Minimalist": "clean lines, empty space, simplicity, sparse detail",
"Isometric": "geometric, three-dimensional, balanced, structured",
"Vignette": "soft edges, focus on center, dramatic fade",
"Line Art": "outlined, monochromatic, graphic look, clean edges",
"Abstract": "geometric shapes, colorful, modern art, non-representational",
"Symmetrical": "balanced, mirrored, harmony, orderly composition",
"Chaos": "disorderly, energetic, dynamic, complex layout",
"Centered Composition": "subject-centered, balanced, focal point",
"Dynamic Composition": "angled, kinetic, action-oriented, strong movement"
}
},
"Photography and Realism": {
"categories": ["none", "Analog Film: Kodachrome", "Analog Film: Black & White", "DSLR: Portrait", "DSLR: Landscape", "Cinematic Still: Epic", "Cinematic Still: Vintage", "HDR", "Long Exposure", "Vintage", "Tilt-shift", "Studio Portrait", "Macro"],
"tags": {
"none": "",
"Analog Film: Kodachrome": "vintage colors, grainy, nostalgic, warm tones",
"Analog Film: Black & White": "monochrome, grainy, retro look, high contrast",
"DSLR: Portrait": "sharp focus, bokeh, high resolution, face details",
"DSLR: Landscape": "wide shot, high clarity, vibrant colors, scenic",
"Cinematic Still: Epic": "dramatic, sweeping views, vivid lighting, deep focus",
"Cinematic Still: Vintage": "faded tones, grainy, nostalgic, filmic",
"HDR": "vivid colors, high contrast, intense shadows, realistic textures",
"Long Exposure": "blurred motion, light trails, surreal effect",
"Vintage": "sepia tones, aged look, retro, soft focus",
"Tilt-shift": "miniature effect, selective focus, blurred edges",
"Studio Portrait": "well-lit, professional, sharp focus, high detail",
"Macro": "extreme close-up, texture details, fine detail"
}
}
}
+227
View File
@@ -0,0 +1,227 @@
{
"Lighting and Atmosphere": [
{
"name": "Volumetric",
"prompt": "dramatic lighting, volumetric, moody, depth-enhancing light",
"negative_prompt": "flat lighting, no depth, harsh shadows"
},
{
"name": "Cinematic: Epic",
"prompt": "high contrast, sweeping light, vibrant, heroic tones",
"negative_prompt": "low contrast, bland lighting, static"
},
{
"name": "Cinematic: Soft Cinematic",
"prompt": "soft cinematic lighting, warm tones, natural ambiance",
"negative_prompt": "harsh shadows, high contrast, cold tones"
},
{
"name": "Cinematic: Vintage Cinematic",
"prompt": "muted tones, sepia hint, faded colors, nostalgic feel",
"negative_prompt": "sharp contrast, vibrant colors, modern look"
},
{
"name": "Cinematic: Neo-noir",
"prompt": "dark shadows, moody, low saturation, gritty aesthetic",
"negative_prompt": "bright, colorful, cheerful, high saturation"
},
{
"name": "Low-key",
"prompt": "low-key, dim light, dark atmosphere, mysterious vibe",
"negative_prompt": "bright, high-key, vibrant lighting"
},
{
"name": "High-key",
"prompt": "bright, airy, minimal shadows, vibrant tones",
"negative_prompt": "dark, low-key, moody"
},
{
"name": "Natural Light: Golden Hour",
"prompt": "warm orange glow, soft shadows, romantic ambiance",
"negative_prompt": "cool tones, harsh light, midday sun"
},
{
"name": "Natural Light: Overcast",
"prompt": "soft lighting, even tones, neutral shadows",
"negative_prompt": "harsh shadows, bright sun, uneven lighting"
},
{
"name": "Natural Light: Cool Light",
"prompt": "cool light, crisp shadows, daylight, fresh atmosphere",
"negative_prompt": "warm tones, golden hues, soft focus"
},
{
"name": "Artificial Light: Neon",
"prompt": "neon glow, high contrast, intense colors, futuristic look",
"negative_prompt": "natural lighting, muted tones, daylight"
},
{
"name": "Artificial Light: Spotlight",
"prompt": "focused light, isolated subject, theatrical effect",
"negative_prompt": "soft, diffused, ambient lighting"
},
{
"name": "Artificial Light: Studio",
"prompt": "balanced lighting, clean, vibrant colors, soft shadows",
"negative_prompt": "uneven lighting, harsh contrast, natural light"
}
],
"Artistic Medium and Texture": [
{
"name": "3D Render",
"prompt": "3D render, photorealistic, cinematic 3D style",
"negative_prompt": "2D, flat, low detail"
},
{
"name": "Claymation",
"prompt": "clay art, organic texture, handcrafted, playful",
"negative_prompt": "smooth, digital, flat"
},
{
"name": "Low-poly",
"prompt": "low-poly, geometric shapes, minimalist design",
"negative_prompt": "high detail, realistic, complex shapes"
},
{
"name": "Pixel Art: 8-bit",
"prompt": "pixel art, retro, low resolution, 8-bit style",
"negative_prompt": "high resolution, smooth, photorealistic"
},
{
"name": "Pixel Art: 16-bit",
"prompt": "pixel art, 16-bit, retro game aesthetic",
"negative_prompt": "high resolution, smooth gradients, realism"
},
{
"name": "Origami: Paper Fold",
"prompt": "origami art, geometric, folded paper design",
"negative_prompt": "digital, flat, photorealistic"
},
{
"name": "Analog Film: Kodachrome",
"prompt": "Kodachrome film, warm tones, vintage feel",
"negative_prompt": "digital clarity, high saturation, modern"
},
{
"name": "Analog Film: Polaroid",
"prompt": "instant film, retro look, faded colors, vignette",
"negative_prompt": "sharp, high contrast, vibrant colors"
}
],
"Cultural and Genre Influences": [
{
"name": "Cyberpunk: Vaporwave",
"prompt": "vaporwave, neon lights, futuristic, high-tech",
"negative_prompt": "natural lighting, historical, rural"
},
{
"name": "Cyberpunk: Dystopian",
"prompt": "dark atmosphere, gritty, neon urban, dystopian",
"negative_prompt": "bright, colorful, cheerful, rural"
},
{
"name": "Fantasy: High Fantasy",
"prompt": "high fantasy art, magical realism, enchanted scenery",
"negative_prompt": "mundane, realistic, modern"
},
{
"name": "Fantasy: Dark Fantasy",
"prompt": "dark fantasy art, grim, ominous landscapes",
"negative_prompt": "bright, cheerful, modern"
},
{
"name": "Fantasy: Elemental",
"prompt": "elemental fantasy, mystical forces, fire, water",
"negative_prompt": "urban, contemporary, industrial"
},
{
"name": "Anime: Shonen",
"prompt": "shonen anime, dynamic poses, heroic action",
"negative_prompt": "soft, pastel, static"
},
{
"name": "Anime: Shojo",
"prompt": "shojo anime, romantic, elegant, pastel colors",
"negative_prompt": "dark, gritty, muted tones"
},
{
"name": "Anime: Mecha",
"prompt": "mecha anime, futuristic robots, mechanical detail",
"negative_prompt": "natural, organic, soft textures"
},
{
"name": "Comic: Western",
"prompt": "western comic art, bold lines, vibrant colors",
"negative_prompt": "subdued, painterly, realistic proportions"
},
{
"name": "Retro: 80s",
"prompt": "80s retro, neon, vintage, geometric",
"negative_prompt": "modern, minimalist, high-tech"
},
{
"name": "Retro: 90s",
"prompt": "90s grunge, nostalgic, vibrant, pastel",
"negative_prompt": "futuristic, polished, clean"
},
{
"name": "Gothic Horror",
"prompt": "gothic horror art, dark shadows, eerie feel",
"negative_prompt": "bright, warm, cheerful"
}
],
"Composition and Style Structure": [
{
"name": "Isometric: Classic",
"prompt": "isometric, geometric precision, balanced design",
"negative_prompt": "unstructured, dynamic, chaotic"
},
{
"name": "Minimalist: Soft Colors",
"prompt": "minimalist, pastel tones, clean design",
"negative_prompt": "complex, ornate, detailed"
},
{
"name": "Vignette: Soft",
"prompt": "soft vignette, warm focus, subtle shading",
"negative_prompt": "sharp, high contrast, flat edges"
},
{
"name": "Line Art: Detailed",
"prompt": "detailed line art, intricate, fine lines",
"negative_prompt": "broad strokes, painterly, high contrast"
},
{
"name": "Centered Composition: Portrait",
"prompt": "balanced portrait, centered, symmetrical",
"negative_prompt": "off-center, chaotic, asymmetrical"
}
],
"Photography and Realism": [
{
"name": "Analog Film: Kodachrome",
"prompt": "Kodachrome, nostalgic film feel, grainy texture",
"negative_prompt": "digital clarity, high saturation, modern"
},
{
"name": "Photographic: Macro",
"prompt": "sharp focus, detailed close-up, intricate details",
"negative_prompt": "blurry, distant, low detail"
},
{
"name": "Cinematic Still: Action Shot",
"prompt": "cinematic action, motion blur, intense lighting",
"negative_prompt": "static, calm, low energy"
},
{
"name": "35mm: Grainy",
"prompt": "grainy texture, vintage look, old film style",
"negative_prompt": "clean, high definition, modern look"
},
{
"name": "DSLR: High ISO",
"prompt": "grainy, cinematic low light, high sensitivity",
"negative_prompt": "bright, clean, low ISO"
}
]
}
+14 -1
View File
@@ -1 +1,14 @@
from .string_switch_opalsky import NODE_CLASS_MAPPINGS
import os
from .string_switch_opalsky import StringSwitchOpalSky
from .prompt_assistant_opalsky import PromptAssistantOpalSky
WEB_DIRECTORY = os.path.join(os.path.dirname(__file__), "js")
__all__ = ["NODE_CLASS_MAPPINGS", "WEB_DIRECTORY"]
NODE_CLASS_MAPPINGS = {
"StringSwitchOpalSky": StringSwitchOpalSky,
"PromptAssistantOpalSky": PromptAssistantOpalSky,
}
# Optional: print to confirm nodes loaded
print("\033[34mOpalSky Nodes: \033[92mLoaded\033[0m")
Binary file not shown.
Binary file not shown.
Binary file not shown.
+112
View File
@@ -0,0 +1,112 @@
import json
import os
from server import PromptServer
class PromptAssistantOpalSky:
def __init__(self):
self.json_data = self.load_bank_of_styles()
def load_bank_of_styles(self):
# Load the styles_OpalSky.json file
current_directory = os.path.dirname(os.path.realpath(__file__))
json_file_path = os.path.join(current_directory, "styles_OpalSky.json")
if os.path.exists(json_file_path):
with open(json_file_path, "r", encoding="utf-8") as f:
return json.load(f)
return {}
@classmethod
def INPUT_TYPES(s):
instance = PromptAssistantOpalSky()
categories = instance.json_data
# Extract style options from each category and add "none" as the default option
lighting_options = ["none"] + [style['name'] for style in categories.get("Lighting and Atmosphere", [])]
medium_options = ["none"] + [style['name'] for style in categories.get("Artistic Medium and Texture", [])]
genre_options = ["none"] + [style['name'] for style in categories.get("Cultural and Genre Influences", [])]
composition_options = ["none"] + [style['name'] for style in categories.get("Composition and Style Structure", [])]
photography_options = ["none"] + [style['name'] for style in categories.get("Photography and Realism", [])]
return {
"required": {
"text_positive": ("STRING", {"default": "", "multiline": True}),
"text_negative": ("STRING", {"default": "", "multiline": True}),
"Lighting_and_Atmosphere": (lighting_options, {"default": "none"}),
"Artistic_Medium_and_Texture": (medium_options, {"default": "none"}),
"Cultural_and_Genre_Influences": (genre_options, {"default": "none"}),
"Composition_and_Style_Structure": (composition_options, {"default": "none"}),
"Photography_and_Realism": (photography_options, {"default": "none"}),
}
}
RETURN_TYPES = ("STRING", "STRING")
RETURN_NAMES = ("styled_positive", "styled_negative")
FUNCTION = "style_prompts"
def style_prompts(self, text_positive, text_negative,
Lighting_and_Atmosphere, Artistic_Medium_and_Texture,
Cultural_and_Genre_Influences, Composition_and_Style_Structure,
Photography_and_Realism):
categories = self.json_data
# Extract positive and negative styles based on selected categories
positive_styles = [text_positive] # Start with user-input positive prompt
negative_styles = [text_negative] # Start with user-input negative prompt
def get_prompts(category_name, selected_style):
category = categories.get(category_name, [])
style = next((item for item in category if item['name'] == selected_style), None)
if style:
# Replace {prompt} with the user-provided positive or negative prompt as appropriate
positive = style.get("prompt", "").replace("{prompt}", text_positive)
negative = style.get("negative_prompt", "")
return positive, negative
return "", ""
# Append style-specific prompts to positive and negative lists
if Lighting_and_Atmosphere != "none":
pos, neg = get_prompts("Lighting and Atmosphere", Lighting_and_Atmosphere)
positive_styles.append(pos)
negative_styles.append(neg)
if Artistic_Medium_and_Texture != "none":
pos, neg = get_prompts("Artistic Medium and Texture", Artistic_Medium_and_Texture)
positive_styles.append(pos)
negative_styles.append(neg)
if Cultural_and_Genre_Influences != "none":
pos, neg = get_prompts("Cultural and Genre Influences", Cultural_and_Genre_Influences)
positive_styles.append(pos)
negative_styles.append(neg)
if Composition_and_Style_Structure != "none":
pos, neg = get_prompts("Composition and Style Structure", Composition_and_Style_Structure)
positive_styles.append(pos)
negative_styles.append(neg)
if Photography_and_Realism != "none":
pos, neg = get_prompts("Photography and Realism", Photography_and_Realism)
positive_styles.append(pos)
negative_styles.append(neg)
# Concatenate the final styled positive and negative prompts
styled_positive = ", ".join(filter(None, positive_styles))
styled_negative = ", ".join(filter(None, negative_styles))
# Emit the update_preview event to notify the frontend
PromptServer.instance.send_sync("opalsky.promptassistant.update_preview", {
"styled_positive": styled_positive,
"styled_negative": styled_negative
})
return styled_positive, styled_negative
# Node Class Mapping
NODE_CLASS_MAPPINGS = {
"PromptAssistantOpalSky": PromptAssistantOpalSky
}
NODE_DISPLAY_NAME_MAPPINGS = {
"PromptAssistantOpalSky": "Prompt Assistant OpalSky"
}
+96 -58
View File
@@ -1,26 +1,50 @@
import json
import os
class String_Switch_OpalSky:
class StringSwitchOpalSky:
def __init__(self):
# Load the JSON file with predefined styles (bank of styles)
self.json_data = self.load_bank_of_styles()
# Define preset mappings
self.presets = {
"Cinematic Noir": {
"Lighting_and_Atmosphere": "Cinematic: Neo-noir",
"Artistic_Medium_and_Texture": "Digital Painting: Hyperrealistic",
"Cultural_and_Genre_Influences": "Gothic Horror",
"Composition_and_Style_Structure": "Cinematic: Dramatic",
"Photography_and_Realism": "Analog Film: Black & White"
},
"Fantasy Illustration": {
"Lighting_and_Atmosphere": "Natural Light: Golden Hour",
"Artistic_Medium_and_Texture": "Digital Painting: Concept Art",
"Cultural_and_Genre_Influences": "Fantasy: High Fantasy",
"Composition_and_Style_Structure": "Centered Composition",
"Photography_and_Realism": "DSLR: Portrait"
},
"Retro Sci-Fi": {
"Lighting_and_Atmosphere": "Artificial Light: Neon",
"Artistic_Medium_and_Texture": "Pixel Art",
"Cultural_and_Genre_Influences": "Sci-Fi: Alien Worlds",
"Composition_and_Style_Structure": "Isometric",
"Photography_and_Realism": "HDR"
}
}
# Load bank of styles from a JSON file
def load_bank_of_styles(self):
current_directory = os.path.dirname(os.path.realpath(__file__))
json_file_path = os.path.join(current_directory, "style_bank.json") # Update the path as necessary
json_file_path = os.path.join(current_directory, "styles.json") # Ensure this matches the actual file name
if os.path.exists(json_file_path):
with open(json_file_path, "r", encoding="utf-8") as f:
return json.load(f)
return {}
@classmethod
def INPUT_TYPES(s):
def INPUT_TYPES(cls):
# Initialize to access the predefined styles
instance = String_Switch_OpalSky()
instance = cls()
categories = instance.json_data
# Extract categories for each predefined style
lighting_options = categories.get("Lighting and Atmosphere", {}).get("categories", [])
medium_options = categories.get("Artistic Medium and Texture", {}).get("categories", [])
@@ -28,86 +52,100 @@ class String_Switch_OpalSky:
composition_options = categories.get("Composition and Style Structure", {}).get("categories", [])
photography_options = categories.get("Photography and Realism", {}).get("categories", [])
# Define 5 predefined styles with custom options from the JSON
# Define preset options
presets = ["Custom", "Cinematic Noir", "Fantasy Illustration", "Retro Sci-Fi"]
return {
"required": {
# Toggle for using styles or custom strings
"use_styles": ("BOOLEAN", {"default": False}),
# Custom strings section with styling
"use_custom_strings": ("BOOLEAN", {"default": True}),
# Predefined styles
"use_styles": ("BOOLEAN", {"default": False}),
"string_1": ("STRING", {"default": "", "multiline": True}),
"switch_string_1": ("BOOLEAN", {"default": True, "label": ""}),
"string_2": ("STRING", {"default": "", "multiline": True}),
"switch_string_2": ("BOOLEAN", {"default": True, "label": ""}),
"string_3": ("STRING", {"default": "", "multiline": True}),
"switch_string_3": ("BOOLEAN", {"default": True, "label": ""}),
"string_4": ("STRING", {"default": "", "multiline": True}),
"switch_string_4": ("BOOLEAN", {"default": True, "label": ""}),
"string_5": ("STRING", {"default": "", "multiline": True}),
"switch_string_5": ("BOOLEAN", {"default": True, "label": ""}),
# Preset dropdown
"preset": (presets, {"default": "Custom"}),
# Predefined styles section
"Lighting_and_Atmosphere": (lighting_options, {"default": "none"}),
"switch_Lighting_and_Atmosphere": ("BOOLEAN", {"default": True}),
"Artistic_Medium_and_Texture": (medium_options, {"default": "none"}),
"switch_Artistic_Medium_and_Texture": ("BOOLEAN", {"default": True}),
"Cultural_and_Genre_Influences": (genre_options, {"default": "none"}),
"switch_Cultural_and_Genre_Influences": ("BOOLEAN", {"default": True}),
"Composition_and_Style_Structure": (composition_options, {"default": "none"}),
"switch_Composition_and_Style_Structure": ("BOOLEAN", {"default": True}),
"Photography_and_Realism": (photography_options, {"default": "none"}),
"switch_Photography_and_Realism": ("BOOLEAN", {"default": True}),
# Custom strings
"string_1": ("STRING", {"default": "", "multiline": False}),
"switch_string_1": ("BOOLEAN", {"default": True}),
"string_2": ("STRING", {"default": "", "multiline": False}),
"switch_string_2": ("BOOLEAN", {"default": True}),
"string_3": ("STRING", {"default": "", "multiline": False}),
"switch_string_3": ("BOOLEAN", {"default": True}),
"string_4": ("STRING", {"default": "", "multiline": False}),
"switch_string_4": ("BOOLEAN", {"default": True}),
"string_5": ("STRING", {"default": "", "multiline": False}),
"switch_string_5": ("BOOLEAN", {"default": True}),
}
}
# Method to process the input and return concatenated string
RETURN_TYPES = ("STRING",)
RETURN_NAMES = ("concatenated_string",)
FUNCTION = "concatenate_strings"
def concatenate_strings(self, use_styles, use_custom_strings,
Lighting_and_Atmosphere, switch_Lighting_and_Atmosphere,
Artistic_Medium_and_Texture, switch_Artistic_Medium_and_Texture,
Cultural_and_Genre_Influences, switch_Cultural_and_Genre_Influences,
Composition_and_Style_Structure, switch_Composition_and_Style_Structure,
Photography_and_Realism, switch_Photography_and_Realism,
string_1, switch_string_1, string_2, switch_string_2, string_3, switch_string_3,
string_4, switch_string_4, string_5, switch_string_5):
# Handling predefined styles and corresponding tags from JSON
all_styles = []
if use_styles:
styles_map = self.json_data
if switch_Lighting_and_Atmosphere and Lighting_and_Atmosphere != "none":
all_styles.append(styles_map["Lighting and Atmosphere"]["tags"][Lighting_and_Atmosphere])
if switch_Artistic_Medium_and_Texture and Artistic_Medium_and_Texture != "none":
all_styles.append(styles_map["Artistic Medium and Texture"]["tags"][Artistic_Medium_and_Texture])
if switch_Cultural_and_Genre_Influences and Cultural_and_Genre_Influences != "none":
all_styles.append(styles_map["Cultural and Genre Influences"]["tags"][Cultural_and_Genre_Influences])
if switch_Composition_and_Style_Structure and Composition_and_Style_Structure != "none":
all_styles.append(styles_map["Composition and Style Structure"]["tags"][Composition_and_Style_Structure])
if switch_Photography_and_Realism and Photography_and_Realism != "none":
all_styles.append(styles_map["Photography and Realism"]["tags"][Photography_and_Realism])
# Handling custom strings
def concatenate_strings(self, use_styles, use_custom_strings,
Lighting_and_Atmosphere,
Artistic_Medium_and_Texture,
Cultural_and_Genre_Influences,
Composition_and_Style_Structure,
Photography_and_Realism,
string_1, switch_string_1, string_2, switch_string_2, string_3, switch_string_3,
string_4, switch_string_4, string_5, switch_string_5, preset):
# Apply preset if not "Custom"
if preset != "Custom" and preset in self.presets:
preset_values = self.presets[preset]
Lighting_and_Atmosphere = preset_values.get("Lighting_and_Atmosphere", "none")
Artistic_Medium_and_Texture = preset_values.get("Artistic_Medium_and_Texture", "none")
Cultural_and_Genre_Influences = preset_values.get("Cultural_and_Genre_Influences", "none")
Composition_and_Style_Structure = preset_values.get("Composition_and_Style_Structure", "none")
Photography_and_Realism = preset_values.get("Photography_and_Realism", "none")
# Handle custom strings
custom_strings = []
if use_custom_strings:
custom_strings = [string_1, string_2, string_3, string_4, string_5]
custom_strings = [s for s, switch in zip(custom_strings, [switch_string_1, switch_string_2, switch_string_3, switch_string_4, switch_string_5]) if switch and s]
# Handle predefined styles
all_styles = []
if use_styles:
styles_map = self.json_data
if Lighting_and_Atmosphere != "none":
all_styles.append(styles_map["Lighting and Atmosphere"]["tags"][Lighting_and_Atmosphere])
if Artistic_Medium_and_Texture != "none":
all_styles.append(styles_map["Artistic Medium and Texture"]["tags"][Artistic_Medium_and_Texture])
if Cultural_and_Genre_Influences != "none":
all_styles.append(styles_map["Cultural and Genre Influences"]["tags"][Cultural_and_Genre_Influences])
if Composition_and_Style_Structure != "none":
all_styles.append(styles_map["Composition and Style Structure"]["tags"][Composition_and_Style_Structure])
if Photography_and_Realism != "none":
all_styles.append(styles_map["Photography and Realism"]["tags"][Photography_and_Realism])
# If both use_styles and use_custom_strings are off, return an empty string
# If both `use_styles` and `use_custom_strings` are off, return an empty string
if not use_styles and not use_custom_strings:
return ("",)
# Concatenate styles and custom strings separately
all_strings = all_styles + custom_strings
# Concatenate custom strings first, followed by styles
all_strings = custom_strings + all_styles
result = ", ".join(all_strings)
return (result,)
# Print message on load
print("StringSwitchOpalSky loaded successfully")
# Node class mapping
NODE_CLASS_MAPPINGS = {
"String_Switch_OpalSky": String_Switch_OpalSky
"string_switch_opalsky": StringSwitchOpalSky
}
# Display Name Mapping
NODE_DISPLAY_NAME_MAPPINGS = {
"string_switch_opalsky": "String Switch OpalSky"
}