diff --git a/README.MD b/README.MD index de0028f..0525d2a 100644 --- a/README.MD +++ b/README.MD @@ -80,6 +80,8 @@ When this error has occurred, please check the network environment. ## Update **If the dependency package error after updating, please reinstall the relevant dependency packages.
+* Commit [AutoAdjustV2](#AutoAdjustV2) node, add optional mask input and support for multiple automatic color adjustment modes. +* Due to the upcoming discontinuation of gemini-pro vision services, [PromptTagger](#PromptTagger) and [PromptEmbellish](#PromptEmbellish) have added the "gemini-1.5-flash" API to continue using it. * [Ultra](#Ultra) nodes added the option to run ```VitMatte``` on the CUDA device, resulting in a 5-fold increase in running speed. * Commit [QueueStop](#QueueStop) node, used to terminate the queue operation. * Optimize performance of the ```VitMate``` method for [Ultra](#Ultra) nodes when processing large-size image. @@ -378,6 +380,15 @@ Node Options: * green: Manual adjustment of the green channel. * blue: Manual adjustment of the blue channel. +### AutoAdjustV2 +On the basis of AutoAdjust, add mask input and only calculate the content inside the mask for automatic color adjustment. Add multiple automatic adjustment modes. +![image](image/auto_adjust_v2_example.jpg) + +The following changes have been made based on AutoAdjust: +![image](image/auto_adjust_v2_node.jpg) +* mask: Optional mask input. +* mode: Automatic adjustment mode. "RGB" automatically adjusts according to the three channels of RGB, "lum + sat"automatically adjusts according to luminance and saturation, "luminance" automatically adjusts according to luminance, "saturation" automatically adjusts according to saturation, and "mono" automatically adjusts according to grayscale and outputs monochrome. + ### AutoBrightness Automatically adjust too dark or too bright image to moderate brightness, and support mask input. When mask input, only the content of the mask part is used as the data source of the automatic brightness. The output is still the whole adjusted image. ![image](image/auto_brightness_example.jpg) @@ -696,14 +707,14 @@ Please apply for your API key on [Google AI Studio](https://makersuite.google.co Node options: ![image](image/prompt_tagger_node.jpg) -* api: The Api used. At present, there is only one option, "gemini-pro-vision". +* api: The Api used. At present, there are two options "gemini-1. 5-flash" and "google-gemini". * token_limit: The maximum token limit for generating prompt words. * exclude_word: Keywords that need to be excluded. * replace_with_word: That word will replace the exclude_word. ### PromptEmbellish -Enter simple prompt words, output polished prompt words, and support inputting images as references. This node currently uses Google Gemini API as the backend service. Please ensure that the network environment can use Gemini normally. +Enter simple prompt words, output polished prompt words, and support inputting images as references, and support Chinese input. This node currently uses Google Gemini API as the backend service. Please ensure that the network environment can use Gemini normally. Please apply for your API key on [Google AI Studio](https://makersuite.google.com/app/apikey), And fill it in ```api_key.ini```, this file is located in the root directory of the plug-in, and the default name is ```api_key.ini.example```. to use this file for the first time, you need to change the file suffix to ```.ini```. Open it using text editing software, fill in your API key after ```google_api_key=``` and save it. ![image](image/prompt_embellish_example.jpg) @@ -711,7 +722,7 @@ Node options: ![image](image/prompt_embellish_node.jpg) * image: Optional, input image as a reference for prompt words. -* api: The Api used. At present, there is only one option, "google-gemini". +* api: The Api used. At present, there are two options "gemini-1. 5-flash" and "google-gemini". * token_limit: The maximum token limit for generating prompt words. * discribe: Enter a simple description here. supports Chinese text input. diff --git a/README_CN.MD b/README_CN.MD index b197102..c4db12b 100644 --- a/README_CN.MD +++ b/README_CN.MD @@ -80,6 +80,8 @@ git clone https://github.com/chflame163/ComfyUI_LayerStyle.git ## 更新说明 **如果本插件更新后出现依赖包错误,请重新安装相关依赖包。 +* 添加 [AutoAdjustV2](#AutoAdjustV2) 节点,增加可选遮罩输入,增加多种自动调色模式支持。 +* 由于gemini-pro-vision即将停止服务, [PromptTagger](#PromptTagger) 和 [PromptEmbellish](#PromptEmbellish) 添加"gemini-1.5-flash" API以继续使用。 * [Ultra](#Ultra) 节点增加```VitMatte```方法在CUDA设备运行选项,运行速度提升5倍。 * 添加 [QueueStop](#QueueStop) 节点,用于停止队列。 * 优化[Ultra](#Ultra)节点的```VitMatte```方法在处理大尺寸图片时的性能。 @@ -373,6 +375,15 @@ git clone https://github.com/chflame163/ComfyUI_LayerStyle.git * green: 绿色通道手动调整。 * blue: 蓝色通道手动调整。 +### AutoAdjustV2 +在AutoAdjust基础上增加遮罩输入, 仅计算遮罩内的内容进行自动调色。增加多种自动调整模式。 +![image](image/auto_adjust_v2_example.jpg) + +在AutoAdjust基础上进行了如下改变: +![image](image/auto_adjust_v2_node.jpg) +* mask:可选遮罩输入。 +* mode: 自动调整模式。"RGB"按RGB三个通道自动调整,"lum + sat"按亮度和饱和度自动调整,"luminance"按亮度自动调整,"saturation"按饱和度自动调整, "mono"按灰度自动调整并输出单色。 + ### AutoBrightness 将过暗或过亮的图片自动调整到适中的亮度,支持遮罩输入。有遮罩输入时仅以遮罩部分的内容作为自动亮度的数据来源。输出仍然是整个调整后的图像。 ![image](image/auto_brightness_example.jpg) @@ -686,13 +697,13 @@ ImageScaleByAspectRatio的V2升级版 节点选项说明: ![image](image/prompt_tagger_node.jpg) -* api: 使用的Api。目前只有"gemini-pro-vision"一个选项。 +* api: 使用的Api。有"gemini-1.5-flash"和"google-gemini"两个选项。 * token_limit: 生成提示词的最大token限制。 * exclude_word: 需要排除的关键词。 * replace_with_word: 替换exclude_word的关键词。 ### PromptEmbellish -输入简单的提示词,输出经过润色的提示词,支持输入图片作为参考。这个节点目前使用Google Gemini API作为后端服务,请确保网络环境可以正常使用Gemini。 +输入简单的提示词,输出经过润色的提示词,支持输入图片作为参考,支持中文输入。这个节点目前使用Google Gemini API作为后端服务,请确保网络环境可以正常使用Gemini。 请在[Google AI Studio](https://makersuite.google.com/app/apikey)申请你的API key, 并将其填到```api_key.ini```, 这个文件位于插件根目录下, 默认名字是```api_key.ini.example```, 初次使用这个文件需将文件后缀改为.ini。用文本编辑软件打开,在```google_api_key=```后面填入你的API key并保存。 ![image](image/prompt_embellish_example.jpg) @@ -700,7 +711,7 @@ ImageScaleByAspectRatio的V2升级版 ![image](image/prompt_embellish_node.jpg) * image: 可选项,输入图像作为提示词参考。 -* api: 使用的Api。目前只有"google-gemini"一个选项。 +* api: 使用的Api。有"gemini-1.5-flash"和"google-gemini"两个选项。 * token_limit: 生成提示词的最大token限制。 * discribe: 在这里输入简单的描述。支持中文。 diff --git a/image/auto_adjust_v2_example.jpg b/image/auto_adjust_v2_example.jpg new file mode 100644 index 0000000..9bf2e89 Binary files /dev/null and b/image/auto_adjust_v2_example.jpg differ diff --git a/image/auto_adjust_v2_node.jpg b/image/auto_adjust_v2_node.jpg new file mode 100644 index 0000000..909ac77 Binary files /dev/null and b/image/auto_adjust_v2_node.jpg differ diff --git a/image/prompt_embellish_example.jpg b/image/prompt_embellish_example.jpg index 4cc14d8..e65d18f 100644 Binary files a/image/prompt_embellish_example.jpg and b/image/prompt_embellish_example.jpg differ diff --git a/py/color_correct_auto_adjust_v2.py b/py/color_correct_auto_adjust_v2.py new file mode 100644 index 0000000..66be8c4 --- /dev/null +++ b/py/color_correct_auto_adjust_v2.py @@ -0,0 +1,143 @@ +from .imagefunc import * + +NODE_NAME = 'AutoAdjustV2' + +class AutoAdjustV2: + + def __init__(self): + pass + + @classmethod + def INPUT_TYPES(self): + mode_list = ["RGB", "lum + sat", "mono", "luminance", "saturation"] + return { + "required": { + "image": ("IMAGE", ), # + "strength": ("INT", {"default": 100, "min": 0, "max": 100, "step": 1}), + "brightness": ("INT", {"default": 0, "min": -100, "max": 100, "step": 1}), + "contrast": ("INT", {"default": 0, "min": -100, "max": 100, "step": 1}), + "saturation": ("INT", {"default": 0, "min": -100, "max": 100, "step": 1}), + "red": ("INT", {"default": 0, "min": -100, "max": 100, "step": 1}), + "green": ("INT", {"default": 0, "min": -100, "max": 100, "step": 1}), + "blue": ("INT", {"default": 0, "min": -100, "max": 100, "step": 1}), + "mode": (mode_list, ), + }, + "optional": { + "mask": ("MASK", ), + } + } + + RETURN_TYPES = ("IMAGE",) + RETURN_NAMES = ("image",) + FUNCTION = 'auto_adjust_v2' + CATEGORY = '😺dzNodes/LayerColor' + + + def auto_adjust_v2(self, image, strength, brightness, contrast, saturation, red, green, blue, mode, mask=None): + + def auto_level_gray(image, mask): + gray_image = Image.new("L", image.size, color='gray') + gray_image.paste(image.convert('L'), mask=mask) + return normalize_gray(gray_image) + + if brightness < 0: + brightness_offset = brightness / 100 + 1 + else: + brightness_offset = brightness / 50 + 1 + if contrast < 0: + contrast_offset = contrast / 100 + 1 + else: + contrast_offset = contrast / 50 + 1 + if saturation < 0: + saturation_offset = saturation / 100 + 1 + else: + saturation_offset = saturation / 50 + 1 + + l_images = [] + l_masks = [] + ret_images = [] + + for l in image: + l_images.append(torch.unsqueeze(l, 0)) + m = tensor2pil(l) + if m.mode == 'RGBA': + l_masks.append(m.split()[-1]) + else: + l_masks.append(Image.new('L', m.size, 'white')) + if mask is not None: + if mask.dim() == 2: + mask = torch.unsqueeze(mask, 0) + l_masks = [] + for m in mask: + l_masks.append(tensor2pil(torch.unsqueeze(m, 0)).convert('L')) + + max_batch = max(len(l_images), len(l_masks)) + for i in range(max_batch): + _image = l_images[i] if i < len(l_images) else l_images[-1] + _mask = l_masks[i] if i < len(l_masks) else l_masks[-1] + orig_image = tensor2pil(_image) + + if mode == 'RGB': + r, g, b, _ = image_channel_split(orig_image, mode = 'RGB') + r = auto_level_gray(r, _mask) + g = auto_level_gray(g, _mask) + b = auto_level_gray(b, _mask) + ret_image = image_channel_merge((r, g, b), 'RGB') + elif mode == 'lum + sat': + h, s, v, _ = image_channel_split(orig_image, mode = 'HSV') + s = auto_level_gray(s, _mask) + ret_image = image_channel_merge((h, s, v), 'HSV') + l, a, b, _ = image_channel_split(ret_image, mode = 'LAB') + l = auto_level_gray(l, _mask) + ret_image = image_channel_merge((l, a, b), 'LAB') + elif mode == 'luminance': + l, a, b, _ = image_channel_split(orig_image, mode = 'LAB') + l = auto_level_gray(l, _mask) + ret_image = image_channel_merge((l, a, b), 'LAB') + elif mode == 'saturation': + h, s, v, _ = image_channel_split(orig_image, mode = 'HSV') + s = auto_level_gray(s, _mask) + ret_image = image_channel_merge((h, s, v), 'HSV') + else: # mono + gray = orig_image.convert('L') + ret_image = auto_level_gray(gray, _mask).convert('RGB') + + if (red or green or blue) and mode != "mono": + r, g, b, _ = image_channel_split(ret_image, mode='RGB') + if red: + r = gamma_trans(r, self.balance_to_gamma(red)).convert('L') + if green: + g = gamma_trans(g, self.balance_to_gamma(green)).convert('L') + if blue: + b = gamma_trans(b, self.balance_to_gamma(blue)).convert('L') + ret_image = image_channel_merge((r, g, b), 'RGB') + + if brightness: + brightness_image = ImageEnhance.Brightness(ret_image) + ret_image = brightness_image.enhance(factor=brightness_offset) + if contrast: + contrast_image = ImageEnhance.Contrast(ret_image) + ret_image = contrast_image.enhance(factor=contrast_offset) + if saturation: + color_image = ImageEnhance.Color(ret_image) + ret_image = color_image.enhance(factor=saturation_offset) + ret_image = chop_image_v2(orig_image, ret_image, blend_mode="normal", opacity=strength) + ret_image.paste(orig_image, mask=ImageChops.invert(_mask)) + if orig_image.mode == 'RGBA': + ret_image = RGB2RGBA(ret_image, orig_image.split()[-1]) + + ret_images.append(pil2tensor(ret_image)) + + log(f"{NODE_NAME} Processed {len(ret_images)} image(s).", message_type='finish') + return (torch.cat(ret_images, dim=0),) + + def balance_to_gamma(self, balance:int) -> float: + return 0.00005 * balance * balance - 0.01 * balance + 1 + +NODE_CLASS_MAPPINGS = { + "LayerColor: AutoAdjustV2": AutoAdjustV2 +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "LayerColor: AutoAdjustV2": "LayerColor: AutoAdjust V2" +} \ No newline at end of file diff --git a/py/prompt_embellish.py b/py/prompt_embellish.py index 3849520..c2290cd 100644 --- a/py/prompt_embellish.py +++ b/py/prompt_embellish.py @@ -9,7 +9,7 @@ class PromptEmbellish: @classmethod def INPUT_TYPES(self): - api_list = ['google-gemini'] + api_list = ['gemini-1.5-flash', 'gemini-pro-vision'] return { "required": { "api": (api_list,), @@ -77,10 +77,10 @@ class PromptEmbellish: f"Only respond with the prompt itself, but embellish it." ) _image = tensor2pil(image).convert('RGB') - model = genai.GenerativeModel('gemini-pro-vision', + model = genai.GenerativeModel(api, generation_config=gemini_generate_config, safety_settings=gemini_safety_settings) - log(f"{NODE_NAME}: Request to gemini-pro-vision...") + log(f"{NODE_NAME}: Request to {api}...") response = model.generate_content([second_step_prompt, _image]) print(response) ret_text = response.text diff --git a/py/prompt_tagger.py b/py/prompt_tagger.py index 6f198e2..394927e 100644 --- a/py/prompt_tagger.py +++ b/py/prompt_tagger.py @@ -9,7 +9,7 @@ class PromptTagger: @classmethod def INPUT_TYPES(self): - api_list = ['gemini-pro-vision'] + api_list = ['gemini-1.5-flash', 'gemini-pro-vision'] return { "required": { @@ -37,36 +37,33 @@ class PromptTagger: prompt = ("You are creating a prompt for Stable Diffusion to generate an image. " "First step: describe this image, then put description into text. " "Second step: generate a text prompt for based on first step. " - "Only respond with the prompt itself, but embellish it. ") + "Only respond with the prompt itself. ") prompt = f"{prompt}As needed keep it under {token_limit} tokens." - - - if api == 'gemini-pro-vision': - model = genai.GenerativeModel(api, - generation_config=gemini_generate_config, - safety_settings=gemini_safety_settings) - genai.configure(api_key=get_api_key('google_api_key'), transport='rest') - log(f"{NODE_NAME}: Request to gemini-pro-vision...") - response = model.generate_content([prompt, _image]) - ret_text = response.text - ret_text = ret_text[ret_text.rfind(':') + 1:] - log(f"{NODE_NAME}: Gemini response is:\n\033[1;36m{ret_text}\033[m") - if len(exclude_word) > 0: - if len(replace_with_word) > 0: - ret_text = replace_case(exclude_word, replace_with_word, ret_text) - refine_model = genai.GenerativeModel('gemini-pro', - generation_config=gemini_generate_config, - safety_settings=gemini_safety_settings - ) - response = refine_model.generate_content( - f'You are creating a prompt for Stable Diffusion to generate an image. ' - f'First step: Replace "{exclude_word}" and its synonyms with "{replace_with_word}" in the following text:{ret_text}' - f'Second step: Correct the grammar errors for based on first step.') - ret_text = response.text + model = genai.GenerativeModel(api, + generation_config=gemini_generate_config, + safety_settings=gemini_safety_settings) + genai.configure(api_key=get_api_key('google_api_key'), transport='rest') + log(f"{NODE_NAME}: Request to {api}...") + response = model.generate_content([prompt, _image]) + ret_text = response.text + ret_text = ret_text[ret_text.rfind(':') + 1:] + log(f"{NODE_NAME}: Gemini response is:\n\033[1;36m{ret_text}\033[m") + if len(exclude_word) > 0: if len(replace_with_word) > 0: - ret_text = ret_text.replace(replace_with_word, f"({replace_with_word})") - log(f"{NODE_NAME}: Tagger prompt is:\n\033[1;36m{ret_text}\033[m") + ret_text = replace_case(exclude_word, replace_with_word, ret_text) + refine_model = genai.GenerativeModel('gemini-pro', + generation_config=gemini_generate_config, + safety_settings=gemini_safety_settings + ) + response = refine_model.generate_content( + f'You are creating a prompt for Stable Diffusion to generate an image. ' + f'First step: Replace "{exclude_word}" and its synonyms with "{replace_with_word}" in the following text:{ret_text}' + f'Second step: Correct the grammar errors for based on first step.') + ret_text = response.text + if len(replace_with_word) > 0: + ret_text = ret_text.replace(replace_with_word, f"({replace_with_word})") + log(f"{NODE_NAME}: Tagger prompt is:\n\033[1;36m{ret_text}\033[m") log(f"{NODE_NAME} Processed.", message_type='finish') return (ret_text,) diff --git a/pyproject.toml b/pyproject.toml index 4f940c9..7f297a1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "comfyui_layerstyle" description = "A set of nodes for ComfyUI it generate image like Adobe Photoshop's Layer Style. the Drop Shadow is first completed node, and follow-up work is in progress." -version = "1.0.11" +version = "1.0.12" license = "MIT" dependencies = ["numpy", "pillow", "torch", "matplotlib", "Scipy", "scikit_image", "opencv-contrib-python", "pymatting", "segment_anything", "timm", "addict", "yapf", "colour-science", "wget", "mediapipe", "loguru", "typer_config", "fastapi", "rich", "google-generativeai", "diffusers", "omegaconf", "tqdm", "transformers", "kornia", "image-reward", "ultralytics", "blend_modes", "blind-watermark", "qrcode", "pyzbar", "psd-tools"] diff --git a/workflow/auto_adjust_v2_example.json b/workflow/auto_adjust_v2_example.json new file mode 100644 index 0000000..ca0ca1c --- /dev/null +++ b/workflow/auto_adjust_v2_example.json @@ -0,0 +1,255 @@ +{ + "last_node_id": 5, + "last_link_id": 5, + "nodes": [ + { + "id": 3, + "type": "LayerMask: RmBgUltra V2", + "pos": [ + 994, + 904 + ], + "size": { + "0": 315, + "1": 246 + }, + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [ + { + "name": "image", + "type": "IMAGE", + "link": 2 + } + ], + "outputs": [ + { + "name": "image", + "type": "IMAGE", + "links": null, + "shape": 3 + }, + { + "name": "mask", + "type": "MASK", + "links": [ + 3, + 4 + ], + "shape": 3, + "slot_index": 1 + } + ], + "properties": { + "Node name for S&R": "LayerMask: RmBgUltra V2" + }, + "widgets_values": [ + "VITMatte(local)", + 6, + 6, + 0.01, + 0.99, + true, + "cuda", + 2 + ] + }, + { + "id": 4, + "type": "LayerMask: MaskPreview", + "pos": [ + 1411, + 918 + ], + "size": [ + 300.41042508952887, + 267.44535713293635 + ], + "flags": {}, + "order": 3, + "mode": 0, + "inputs": [ + { + "name": "mask", + "type": "MASK", + "link": 4 + } + ], + "properties": { + "Node name for S&R": "LayerMask: MaskPreview" + } + }, + { + "id": 5, + "type": "PreviewImage", + "pos": [ + 1834, + 579 + ], + "size": [ + 464.03425232437985, + 306.70342563597603 + ], + "flags": {}, + "order": 4, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 5 + } + ], + "properties": { + "Node name for S&R": "PreviewImage" + } + }, + { + "id": 1, + "type": "LayerColor: AutoAdjustV2", + "pos": [ + 1401, + 575 + ], + "size": { + "0": 315, + "1": 246 + }, + "flags": {}, + "order": 2, + "mode": 0, + "inputs": [ + { + "name": "image", + "type": "IMAGE", + "link": 1, + "slot_index": 0 + }, + { + "name": "mask", + "type": "MASK", + "link": 3 + } + ], + "outputs": [ + { + "name": "image", + "type": "IMAGE", + "links": [ + 5 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "LayerColor: AutoAdjustV2" + }, + "widgets_values": [ + 100, + 0, + 0, + 0, + 0, + 0, + 0, + "lum + sat" + ] + }, + { + "id": 2, + "type": "LoadImage", + "pos": [ + 571, + 572 + ], + "size": [ + 315, + 314 + ], + "flags": {}, + "order": 0, + "mode": 0, + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 1, + 2 + ], + "shape": 3, + "slot_index": 0 + }, + { + "name": "MASK", + "type": "MASK", + "links": null, + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "LoadImage" + }, + "widgets_values": [ + "1344x768_girl2.png", + "image" + ] + } + ], + "links": [ + [ + 1, + 2, + 0, + 1, + 0, + "IMAGE" + ], + [ + 2, + 2, + 0, + 3, + 0, + "IMAGE" + ], + [ + 3, + 3, + 1, + 1, + 1, + "MASK" + ], + [ + 4, + 3, + 1, + 4, + 0, + "MASK" + ], + [ + 5, + 1, + 0, + 5, + 0, + "IMAGE" + ] + ], + "groups": [], + "config": {}, + "extra": { + "ds": { + "scale": 0.9090909090909091, + "offset": [ + -54.10001770726194, + 80.30189335530713 + ] + } + }, + "version": 0.4 +} \ No newline at end of file diff --git a/workflow/prompt_embellish_example.json b/workflow/prompt_embellish_example.json new file mode 100644 index 0000000..34b8407 --- /dev/null +++ b/workflow/prompt_embellish_example.json @@ -0,0 +1,479 @@ +{ + "last_node_id": 14, + "last_link_id": 15, + "nodes": [ + { + "id": 8, + "type": "VAEDecode", + "pos": [ + 1430, + 380 + ], + "size": { + "0": 210, + "1": 46 + }, + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [ + { + "name": "samples", + "type": "LATENT", + "link": 7 + }, + { + "name": "vae", + "type": "VAE", + "link": 8 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 11 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "VAEDecode" + } + }, + { + "id": 7, + "type": "CLIPTextEncode", + "pos": [ + 630, + 480 + ], + "size": [ + 210, + 76 + ], + "flags": {}, + "order": 3, + "mode": 0, + "inputs": [ + { + "name": "clip", + "type": "CLIP", + "link": 5 + } + ], + "outputs": [ + { + "name": "CONDITIONING", + "type": "CONDITIONING", + "links": [ + 6 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "CLIPTextEncode" + }, + "widgets_values": [ + "text, watermark" + ] + }, + { + "id": 6, + "type": "CLIPTextEncode", + "pos": [ + 630, + 360 + ], + "size": [ + 221.5748086041326, + 54 + ], + "flags": {}, + "order": 4, + "mode": 0, + "inputs": [ + { + "name": "clip", + "type": "CLIP", + "link": 3 + }, + { + "name": "text", + "type": "STRING", + "link": 10, + "widget": { + "name": "text" + } + } + ], + "outputs": [ + { + "name": "CONDITIONING", + "type": "CONDITIONING", + "links": [ + 4 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "CLIPTextEncode" + }, + "widgets_values": [ + "beautiful scenery nature glass bottle landscape, , purple galaxy bottle," + ] + }, + { + "id": 5, + "type": "EmptyLatentImage", + "pos": [ + 630, + 640 + ], + "size": { + "0": 315, + "1": 106 + }, + "flags": {}, + "order": 0, + "mode": 0, + "outputs": [ + { + "name": "LATENT", + "type": "LATENT", + "links": [ + 2 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "EmptyLatentImage" + }, + "widgets_values": [ + 832, + 1152, + 1 + ] + }, + { + "id": 4, + "type": "CheckpointLoaderSimple", + "pos": [ + 190, + 430 + ], + "size": [ + 339.3543294428463, + 98 + ], + "flags": {}, + "order": 1, + "mode": 0, + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 1 + ], + "slot_index": 0 + }, + { + "name": "CLIP", + "type": "CLIP", + "links": [ + 3, + 5 + ], + "slot_index": 1 + }, + { + "name": "VAE", + "type": "VAE", + "links": [ + 8 + ], + "slot_index": 2 + } + ], + "properties": { + "Node name for S&R": "CheckpointLoaderSimple" + }, + "widgets_values": [ + "SDXL\\realvisxlV40_v40Bakedvae.safetensors" + ] + }, + { + "id": 11, + "type": "PreviewImage", + "pos": [ + 1700, + 230 + ], + "size": [ + 423.20624594675246, + 602.5239787263979 + ], + "flags": {}, + "order": 8, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 11 + } + ], + "properties": { + "Node name for S&R": "PreviewImage" + } + }, + { + "id": 10, + "type": "LayerUtility: PromptEmbellish", + "pos": [ + 190, + 620 + ], + "size": [ + 332.8937369680273, + 125.21004277188638 + ], + "flags": {}, + "order": 2, + "mode": 0, + "inputs": [ + { + "name": "image", + "type": "IMAGE", + "link": null + } + ], + "outputs": [ + { + "name": "text", + "type": "STRING", + "links": [ + 10, + 12 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "LayerUtility: PromptEmbellish" + }, + "widgets_values": [ + "gemini-1.5-flash", + 40, + "一只猫,夜晚,森林" + ] + }, + { + "id": 12, + "type": "ShowText|pysssss", + "pos": [ + 630, + 140 + ], + "size": [ + 358.2118278720675, + 149.85371460993542 + ], + "flags": {}, + "order": 5, + "mode": 0, + "inputs": [ + { + "name": "text", + "type": "STRING", + "link": 12, + "widget": { + "name": "text" + } + } + ], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": null, + "shape": 6 + } + ], + "properties": { + "Node name for S&R": "ShowText|pysssss" + }, + "widgets_values": [ + "", + "A lone cat, its emerald eyes piercing the darkness, stands amidst the towering trees of an ancient forest. The moon casts an ethereal glow upon the scene, illuminating the intricate patterns of the cat's sleek fur. The air is thick with the scent of pine needles and damp earth, creating an atmosphere of mystery and enchantment." + ] + }, + { + "id": 3, + "type": "KSampler", + "pos": [ + 1080, + 380 + ], + "size": { + "0": 315, + "1": 262 + }, + "flags": {}, + "order": 6, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 1 + }, + { + "name": "positive", + "type": "CONDITIONING", + "link": 4 + }, + { + "name": "negative", + "type": "CONDITIONING", + "link": 6 + }, + { + "name": "latent_image", + "type": "LATENT", + "link": 2 + } + ], + "outputs": [ + { + "name": "LATENT", + "type": "LATENT", + "links": [ + 7 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "KSampler" + }, + "widgets_values": [ + 712764536591081, + "fixed", + 20, + 8, + "euler", + "normal", + 1 + ] + } + ], + "links": [ + [ + 1, + 4, + 0, + 3, + 0, + "MODEL" + ], + [ + 2, + 5, + 0, + 3, + 3, + "LATENT" + ], + [ + 3, + 4, + 1, + 6, + 0, + "CLIP" + ], + [ + 4, + 6, + 0, + 3, + 1, + "CONDITIONING" + ], + [ + 5, + 4, + 1, + 7, + 0, + "CLIP" + ], + [ + 6, + 7, + 0, + 3, + 2, + "CONDITIONING" + ], + [ + 7, + 3, + 0, + 8, + 0, + "LATENT" + ], + [ + 8, + 4, + 2, + 8, + 1, + "VAE" + ], + [ + 10, + 10, + 0, + 6, + 1, + "STRING" + ], + [ + 11, + 8, + 0, + 11, + 0, + "IMAGE" + ], + [ + 12, + 10, + 0, + 12, + 0, + "STRING" + ] + ], + "groups": [], + "config": {}, + "extra": { + "ds": { + "scale": 0.8264462809917354, + "offset": [ + 651.852869780947, + 412.32328834665384 + ] + } + }, + "version": 0.4 +} \ No newline at end of file