diff --git a/README.md b/README.md index 9c27102..f00e673 100644 --- a/README.md +++ b/README.md @@ -145,6 +145,8 @@ Please try downgrading the ```protobuf``` dependency package to 3.20.3, or set e **If the dependency package error after updating, please double clicking ```repair_dependency.bat``` (for Official ComfyUI Protable) or ```repair_dependency_aki.bat``` (for ComfyUI-aki-v1.x) in the plugin folder to reinstall the dependency packages. +* Commit [GeminiImageEdit](#GeminiImageEdit) node, support using gemini-2.0-flash-exp-image-generation API for image editing. +* Commit [GeminiV2](#GeminiV2) and [ObjectDetectorGeminiV2](#ObjectDetectorGeminiV2) nodes, used google-genai dependency package that supports the gemini-2.0-flash-exp and gemini-2.5-pro-exp-03-25 models. * Add QuarkNetdisk model download link. * Support numpy 2.x dependency package. * Commit [DeepseekAPI_V2](#DeepseekAPI_V2) noee, supporting AliYun and VolcEngine API. @@ -339,6 +341,32 @@ Node options: * system_prompt: The system prompt. * user_prompt: The user prompt. +### GeminiV2 +On the basis of Gemini nodes, switch to using the new google-genai dependency package, which supports the latest gemini-2.0-flash, gemini-2.0-flash-lite, and gemini-2.5-pro-exp-03-25 models. +![image](image/gemini_v2_example.jpg) + +Add on the original node: +![image](image/gemini_v2_node.jpg) +* seed: Seed value used when requesting Google API. + + +### GeminiImageEdit +Implement multimodal image editing using the gemini-2.0-flash-exp-image-generation model. +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/gemini_image_edit_example.jpg) + +Node Options: +![image](image/gemini_image_edit_node.jpg) + +* image: The input image. +* image_2: Optional second image input. +* image_3: Optional third image input. +* model: Choose the Gemini model. Currently, only the gemini-2.0-flash-exp-image-generation model is supported. +* temperature: The temperature parameter of Gemini defaults to 0.5. +* seed: Seed value used when requesting Google API. +* control_after_generate: Set whether to change the seed every time. +* user_prompt: The user prompt. + ### DeepSeekAPI Use the DeepSeek API for text inference, supporting multi node context concatenation. Apply for an API key for free at [https://platform.deepseek.com/api_keys](https://platform.deepseek.com/api_keys), 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 ```deepseek_api_key=``` and save it. @@ -929,6 +957,14 @@ Node Options: * model: Selete Gemini model. * prompt: Describe the object that needs to be identified. +### ObjectDetectorGeminiV2 +On the basis of the ObjectDetectorGemini node, change to using a new google-genai dependency package that supports the latest gemini-2.5-pro-exp-03-25 model. + +Node Options: +![image](image/object_detector_gemini_v2_node.jpg) + +Same as ObjectDetectorGemini + ### ObjectDetectorFL2 Use the Florence2 model to identify objects in images and output recognition box data. diff --git a/README_CN.MD b/README_CN.MD index db2987d..8a6504a 100644 --- a/README_CN.MD +++ b/README_CN.MD @@ -121,6 +121,8 @@ If this call came from a _pb2.py file, your generated code is out of date and mu ## 更新说明 **如果本插件更新后出现依赖包错误,请双击运行插件目录下的```install_requirements.bat```(官方便携包),或 ```install_requirements_aki.bat```(秋叶整合包) 重新安装依赖包。 +* 添加 [GeminiImageEdit](#GeminiImageEdit) 节点,支持使用gemini-2.0-flash-exp-image-generation API进行图像编辑。 +* 添加 [GeminiV2](#GeminiV2) 以及 [ObjectDetectorGeminiV2](#ObjectDetectorGeminiV2) 节点,使用了新的google-genai依赖包,支持最新的gemini-2.0-flash-exp以及gemini-2.5-pro-exp-03-25模型。 * 增加模型下载夸克网盘链接。 * 支持numpy 2.x 依赖包。 * 添加 [DeepseekAPI_V2](#DeepseekAPI_V2) 节点,支持阿里云和火山引擎的deepseek api。 @@ -314,6 +316,34 @@ JoyCaption2的extra_options参数节点。 * system_prompt: 系统提示词。 * user_prompt: 用户提示词。 +### GeminiV2 +在Gemini节点基础上改为使用新的google-genai依赖包,支持最新的gemini-2.0-flash、gemini-2.0-flash-lite以及gemini-2.5-pro-exp-03-25模型。 +![image](image/gemini_v2_example.jpg) + + +在原节点上新增: +![image](image/gemini_v2_node.jpg) + +* seed: 用于请求Google API时的种子值。 + +### GeminiImageEdit +使用gemini-2.0-flash-exp-image-generation 模型实现多模态图片编辑。 +请在[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/gemini_image_edit_example.jpg) + +节点选项说明: +![image](image/gemini_image_edit_node.jpg) + +* image: 图片输入。 +* image_2: 可选第二张图片输入。 +* image_3: 可选第三张图片输入。 +* model: 选择Gemini模型。目前仅支持gemini-2.0-flash-exp-image-generation模型。 +* temperature: Gemini的temperature参数,默认为0.5。 +* seed: 用于请求Google API时的种子值。 +* control_after_generate: 是否每次更改种子。 +* user_prompt: 用户提示词。 + + ### DeepSeekAPI 使用DeepSeek API进行文本推理,支持多节点上下文串联。 在[https://platform.deepseek.com/api_keys](https://platform.deepseek.com/api_keys)申请API Key,并将其填到```api_key.ini```, 这个文件位于插件根目录下, 默认名字是```api_key.ini.example```, 初次使用这个文件需将文件后缀改为.ini。用文本编辑软件打开,在```deepseek_api_key=```后面填入你的API key并保存。 @@ -859,6 +889,15 @@ https://github.com/user-attachments/assets/b2a45c96-4be1-4470-8ceb-addaf301b0cb * prompt: 描述需要识别的对象。 +### ObjectDetectorGeminiV2 +在ObjectDetectorGemini节点基础上改为使用新的google-genai依赖包,支持最新的gemini-2.5-pro-exp-03-25模型。 + + +节点选项说明: +![image](image/object_detector_gemini_v2_node.jpg) + +同ObjectDetectorGemini + ### ObjectDetectorFL2 使用Florence2模型识别图片中的对象,并输出识别框数据。 *请从 [百度网盘](https://pan.baidu.com/s/1hzw9-QiU1vB8pMbBgofZIA?pwd=mfl3)下载模型文件并复制到```ComfyUI/models/florence2```文件夹。 diff --git a/image/gemini_image_edit_example.jpg b/image/gemini_image_edit_example.jpg new file mode 100644 index 0000000..dd0ba05 Binary files /dev/null and b/image/gemini_image_edit_example.jpg differ diff --git a/image/gemini_image_edit_node.jpg b/image/gemini_image_edit_node.jpg new file mode 100644 index 0000000..f5ad907 Binary files /dev/null and b/image/gemini_image_edit_node.jpg differ diff --git a/image/gemini_v2_example.jpg b/image/gemini_v2_example.jpg new file mode 100644 index 0000000..aca07ac Binary files /dev/null and b/image/gemini_v2_example.jpg differ diff --git a/image/gemini_v2_node.jpg b/image/gemini_v2_node.jpg new file mode 100644 index 0000000..4028dcb Binary files /dev/null and b/image/gemini_v2_node.jpg differ diff --git a/image/object_detector_gemini_v2_node.jpg b/image/object_detector_gemini_v2_node.jpg new file mode 100644 index 0000000..e28642f Binary files /dev/null and b/image/object_detector_gemini_v2_node.jpg differ diff --git a/py/gemini.py b/py/gemini.py index 8ca7a57..b138d38 100644 --- a/py/gemini.py +++ b/py/gemini.py @@ -1,7 +1,6 @@ # layerstyle advance -import json -import re +import io from .imagefunc import * def is_only_digits_and_spaces(s:str) -> bool: @@ -94,6 +93,129 @@ class LS_GeminiNode: return (ret_texts,) +class LS_GeminiNode_V2: + + CATEGORY = '😺dzNodes/LayerUtility' + FUNCTION = "run_gemini_v2" + RETURN_TYPES = ("STRING",) + RETURN_NAMES = ("text",) + OUTPUT_IS_LIST = (True,) + + def __init__(self): + self.NODE_NAME = 'GeminiV2' + + @classmethod + def INPUT_TYPES(self): + gemini_model_list = [ + "gemini-2.0-flash-lite", + "gemini-2.0-flash", + "gemini-2.5-pro-exp-03-25", + ] + language_list = ['en', 'zh-CN'] + return { + "required": { + "model": (gemini_model_list,), + "max_output_tokens": ("INT", {"default": 4096, "min": 1, "max": 8192, "step": 1}), + "temperature": ("FLOAT", {"default": 0.5, "min": 0, "max": 2, "step": 0.1}), + "words_limit": ("INT", {"default": 200, "min": 8, "max": 2048, "step": 1}), + "response_language": (language_list,), + "seed": ("INT", {"default": 0, "min": 0, "max": 2147483647}), + "system_prompt": ("STRING", + {"default": "You are creating a prompt for Stable Diffusion to generate an image.", + "multiline": False}), + "user_prompt": ("STRING", { + "default": "Generate a prompt about a girl.", + "multiline": True}), + }, + "optional": { + "image_1": ("IMAGE",), + "image_2": ("IMAGE",), + } + } + + def run_gemini_v2(self, model, system_prompt, user_prompt, max_output_tokens, temperature, + words_limit, response_language, seed, image_1=None, image_2=None): + + + from google import genai + from google.genai import types + ret_texts = [] + + + client = genai.Client(api_key=get_api_key('google_api_key')) + + gen_config = types.GenerateContentConfig( + safety_settings=gemini_safety_settings, + temperature=temperature, + max_output_tokens=max_output_tokens, + seed=seed + ) + + contents = [] + prompt_text = f"USER_INPUT: {user_prompt}\n" \ + f"{system_prompt}\n" \ + f"Follow the USER_INPUT to complete task, Only output the positive prompt, keep response length between {int(words_limit * 0.8)} to {int(words_limit * 1.2)} words." + + contents.append({"text": prompt_text}) + log(f"{self.NODE_NAME}: Request to {model}...") + if image_1 is not None and image_2 is not None: # 2张图 + for index,img in enumerate(image_1): + images = [] + _image1 = tensor2pil(img.unsqueeze(0)).convert('RGB') + images.append(_image1) + _image2 = tensor2pil(image_2[index].unsqueeze(0)).convert('RGB') if index < len(image_2) else tensor2pil(image_2[-1].unsqueeze(0)).convert('RGB') + images.append(_image2) + for i in images: + img_byte_arr = io.BytesIO() + i.save(img_byte_arr, format='PNG') + img_byte_arr.seek(0) + image_bytes = img_byte_arr.read() + img_part = {"inline_data": {"mime_type": "image/png", "data": image_bytes}} + contents.append(img_part) + contents[0]["text"] += "\nUse these reference images as guidance." + + response = client.models.generate_content( + model=model, + contents=contents, + config=gen_config + ) + ret_text = response.text + log(f"{self.NODE_NAME}: Gemini response is:\n\033[1;36m{ret_text}\033[m") + ret_texts.append(ret_text) + elif (image_1 is not None and image_2 is None) or (image_2 is not None and image_1 is None): # 1张图 + _imgs = image_1 if image_1 is not None else image_2 + for img in _imgs: + _image = tensor2pil(img.unsqueeze(0)).convert('RGB') + + img_byte_arr = io.BytesIO() + _image.save(img_byte_arr, format='PNG') + img_byte_arr.seek(0) + image_bytes = img_byte_arr.read() + img_part = {"inline_data": {"mime_type": "image/png", "data": image_bytes}} + contents.append(img_part) + contents[0]["text"] += "\nUse this reference image as guidance." + + response = client.models.generate_content( + model=model, + contents=contents, + config=gen_config + ) + ret_text = response.text + log(f"{self.NODE_NAME}: Gemini response is:\n\033[1;36m{ret_text}\033[m") + ret_texts.append(ret_text) + else: # 无图 + response = client.models.generate_content( + model=model, + contents=contents, + config=gen_config + ) + ret_text = response.text + log(f"{self.NODE_NAME}: Gemini response is:\n\033[1;36m{ret_text}\033[m") + ret_texts.append(ret_text) + + return (ret_texts,) + + class LS_OBJECT_DETECTOR_Gemini: CATEGORY = '😺dzNodes/LayerMask' @@ -135,7 +257,7 @@ class LS_OBJECT_DETECTOR_Gemini: safety_settings=gemini_safety_settings) genai.configure(api_key=get_api_key('google_api_key'), transport='rest') - g_prompt = f"Return a bounding box of {prompt} in this image in [ymin, xmin, ymax, xmax] format." + g_prompt = f"Return a bounding box of {prompt} in this image in [ymin, xmin, ymax, xmax] format. Only return these 4 values, separated by a space, without any extra characters." log(f"{self.NODE_NAME}: Request to {model}...") @@ -143,6 +265,95 @@ class LS_OBJECT_DETECTOR_Gemini: _image = tensor2pil(img.unsqueeze(0)).convert('RGB') response = g_model.generate_content([_image, g_prompt]) ret_text = response.text + + if not is_only_digits_and_spaces(ret_text): + ret_bboxes.append([(-1, -1, 0, 0)]) + ret_previews.append(pil2tensor(_image)) + log(f"{self.NODE_NAME} no object found", message_type='warning') + continue + + y1,x1,y2,x2 = [int(x) for x in ret_text.split()] + + # Convert normalized coordinates to absolute coordinates + x1 = int(x1 / 1000 * _image.width) + y1 = int(y1 / 1000 * _image.height) + x2 = int(x2 / 1000 * _image.width) + y2 = int(y2 / 1000 * _image.height) + bboxes = standardize_bbox([(x1, y1, x2, y2)]) + preview = draw_bounding_boxes(_image.convert("RGB"), bboxes, color="random", line_width=-1) + ret_previews.append(pil2tensor(preview)) + + log(f"{self.NODE_NAME} found {len(bboxes)} object(s)", message_type='info') + ret_bboxes.append(bboxes) + + return (ret_bboxes, torch.cat(ret_previews, dim=0),) + +class LS_OBJECT_DETECTOR_Gemini_V2: + + CATEGORY = '😺dzNodes/LayerMask' + FUNCTION = "run_gemini_detect_v2" + RETURN_TYPES = ("BBOXES", "IMAGE",) + RETURN_NAMES = ("bboxes", "preview",) + # OUTPUT_IS_LIST = (True,) + + def __init__(self): + self.NODE_NAME = 'GeminiDetectV2' + + @classmethod + def INPUT_TYPES(self): + gemini_model_list = [ + "gemini-2.5-pro-exp-03-25", + "gemini-1.5-pro", + ] + + return { + "required": { + "image": ("IMAGE",), + "model": (gemini_model_list,), + "prompt": ("STRING", {"default": "subject"}), + }, + "optional": { + } + } + + def run_gemini_detect_v2(self, image, model, prompt): + + from google import genai + from google.genai import types + ret_bboxes = [] + ret_previews = [] + + client = genai.Client(api_key=get_api_key('google_api_key')) + + gen_config = types.GenerateContentConfig( + safety_settings=gemini_safety_settings, + ) + + contents = [] + prompt_text = f"Return a bounding box of {prompt} in this image in [ymin, xmin, ymax, xmax] format. Only return these 4 values, separated by a space, without any extra characters." + contents.append({"text": prompt_text}) + + log(f"{self.NODE_NAME}: Request to {model}...") + + for img in image: + _image = tensor2pil(img.unsqueeze(0)).convert('RGB') + + img_byte_arr = io.BytesIO() + _image.save(img_byte_arr, format='PNG') + img_byte_arr.seek(0) + image_bytes = img_byte_arr.read() + img_part = {"inline_data": {"mime_type": "image/png", "data": image_bytes}} + contents.append(img_part) + # contents[0]["text"] += f"\nUse this image as find {prompt}'s bounding box." + + response = client.models.generate_content( + model=model, + contents=contents, + config=gen_config + ) + + ret_text = response.text + if not is_only_digits_and_spaces(ret_text): ret_bboxes.append([(-1, -1, 0, 0)]) ret_previews.append(pil2tensor(_image)) @@ -166,12 +377,119 @@ class LS_OBJECT_DETECTOR_Gemini: return (ret_bboxes, torch.cat(ret_previews, dim=0),) +class LS_Gemini_Image_Edit: + + CATEGORY = '😺dzNodes/LayerUtility' + FUNCTION = "run_gemini_image_edit" + RETURN_TYPES = ("IMAGE",) + RETURN_NAMES = ("image",) + + + def __init__(self): + self.NODE_NAME = 'GeminiImageEdit' + + @classmethod + def INPUT_TYPES(self): + gemini_model_list = [ + "gemini-2.0-flash-exp-image-generation", + ] + + return { + "required": { + "image": ("IMAGE",), + "model": (gemini_model_list,), + "temperature": ("FLOAT", {"default": 0.5, "min": 0, "max": 2, "step": 0.1}), + "seed": ("INT", {"default": 0, "min": 0, "max": 2147483647}), + "user_prompt": ("STRING", { + "default": "change the background to forest", + "multiline": True}), + }, + "optional": { + "image_2": ("IMAGE",), + "image_3": ("IMAGE",), + } + } + + def run_gemini_image_edit(self, image, model, temperature, seed, user_prompt, + image_2=None, image_3=None): + + + from google import genai + from google.genai import types + ret_images = [] + + + client = genai.Client(api_key=get_api_key('google_api_key')) + gen_config = types.GenerateContentConfig( + safety_settings=gemini_safety_settings, + temperature=temperature, + seed=seed, + response_modalities=['Text', 'Image'] + ) + + + + + log(f"{self.NODE_NAME}: Request to {model}...") + + for idx,img in enumerate(image): + input_images = [] + input_images.append(tensor2pil(img.unsqueeze(0)).convert('RGB')) + + contents = [] + prompt_text = f"Create a detailed image of: {user_prompt}." + contents.append({"text": prompt_text}) + if image_2 is not None: + img2 = tensor2pil(image_2[idx].unsqueeze(0)).convert('RGB') if idx < len(image_2) else tensor2pil(image_2[-1].unsqueeze(0)).convert('RGB') + input_images.append(img2) + if image_3 is not None: + img3 = tensor2pil(image_3[idx].unsqueeze(0)).convert('RGB') if idx < len(image_3) else tensor2pil(image_3[-1].unsqueeze(0)).convert('RGB') + input_images.append(img3) + + for i in input_images: + img_byte_arr = io.BytesIO() + i.save(img_byte_arr, format='PNG') + img_byte_arr.seek(0) + image_bytes = img_byte_arr.read() + img_part = {"inline_data": {"mime_type": "image/png", "data": image_bytes}} + contents.append(img_part) + if len(input_images) > 1: + contents[0]["text"] += f"\nBased on the first image, Use other reference image as guidance." + else: + contents[0]["text"] += f"\nBased on this image." + + response = client.models.generate_content( + model=model, + contents=contents, + config=gen_config + ) + + for item in response.candidates[0].content.parts: + if hasattr(item, "inline_data") and item.inline_data.mime_type == "image/png": + image_bytes = item.inline_data.data + image_bytes = io.BytesIO(image_bytes) + image_bytes.seek(0) + ret_images.append(pil2tensor(Image.open(image_bytes))) + + if len(ret_images) == 0: + log(f"{self.NODE_NAME} no image response, return original image", message_type='warning') + ret_images=image + + return (ret_images) + + NODE_CLASS_MAPPINGS = { "LayerUtility: Gemini": LS_GeminiNode, + "LayerUtility: GeminiV2": LS_GeminiNode_V2, "LayerMask: ObjectDetectorGemini": LS_OBJECT_DETECTOR_Gemini, + "LayerMask: ObjectDetectorGeminiV2": LS_OBJECT_DETECTOR_Gemini_V2, + "LayerUtility: GeminiImageEdit": LS_Gemini_Image_Edit, } NODE_DISPLAY_NAME_MAPPINGS = { "LayerUtility: Gemini": "LayerUtility: Gemini(Advance)", + "LayerUtility: GeminiV2": "LayerUtility: Gemini V2(Advance)", "LayerMask: ObjectDetectorGemini": "LayerMask: Object Detector Gemini(Advance)", + "LayerMask: ObjectDetectorGeminiV2": "LayerMask: Object Detector Gemini V2(Advance)", + "LayerUtility: GeminiImageEdit": "LayerUtility: Gemini Image Edit(Advance)", } diff --git a/pyproject.toml b/pyproject.toml index 1c510a9..4e01bde 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,9 +1,9 @@ [project] name = "comfyui_layerstyle_advance" description = "The nodes detached from ComfyUI Layer Style are mainly those with complex requirements for dependency packages." -version = "2.0.15" +version = "2.0.16" license = { text = "MIT License" } -dependencies = ["numpy", "matplotlib", "scikit_image", "scikit_learn", "opencv-contrib-python", "pymatting", "timm", "blend_modes", "transformers", "diffusers", "loguru", "colour-science", "huggingface_hub", "segment_anything", "addict", "omegaconf", "yapf", "wget", "iopath", "mediapipe", "typer_config", "fastapi", "rich", "google-generativeai", "ultralytics", "transparent-background", "accelerate", "onnxruntime", "bitsandbytes", "peft", "protobuf", "hydra-core", "blind-watermark", "qrcode", "pyzbar", "psd-tools", "wandb", "zhipuai", "openai"] +dependencies = ["numpy", "matplotlib", "scikit_image", "scikit_learn", "opencv-contrib-python", "pymatting", "timm", "blend_modes", "transformers", "diffusers", "loguru", "colour-science", "huggingface_hub", "segment_anything", "addict", "omegaconf", "yapf", "wget", "iopath", "mediapipe", "typer_config", "fastapi", "rich", "google-generativeai", "ultralytics", "transparent-background", "accelerate", "onnxruntime", "bitsandbytes", "peft", "protobuf", "hydra-core", "blind-watermark", "qrcode", "pyzbar", "psd-tools", "wandb", "zhipuai", "openai","google-genai"] [project.urls] Repository = "https://github.com/chflame163/ComfyUI_LayerStyle_Advance" diff --git a/requirements.txt b/requirements.txt index f222c8a..4f826e7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -22,6 +22,8 @@ typer_config fastapi rich google-generativeai +google-genai>=1.5.0 +pillow>=10.1.0 ultralytics>=8.2.0 transparent-background accelerate>=0.26.0 diff --git a/workflow/gemini_image_edit_example.json b/workflow/gemini_image_edit_example.json new file mode 100644 index 0000000..e36d918 --- /dev/null +++ b/workflow/gemini_image_edit_example.json @@ -0,0 +1,1723 @@ +{ + "id": "0dd7e1d7-34fc-47cf-bf4d-c51029c4391f", + "revision": 0, + "last_node_id": 85, + "last_link_id": 141, + "nodes": [ + { + "id": 24, + "type": "LayerUtility: GeminiV2", + "pos": [ + 269.0139465332031, + -16.73096466064453 + ], + "size": [ + 403.1999816894531, + 300 + ], + "flags": {}, + "order": 10, + "mode": 4, + "inputs": [ + { + "name": "image_1", + "shape": 7, + "type": "IMAGE", + "link": 42 + }, + { + "name": "image_2", + "shape": 7, + "type": "IMAGE", + "link": 43 + } + ], + "outputs": [ + { + "name": "text", + "shape": 6, + "type": "STRING", + "links": [ + 41 + ] + } + ], + "properties": { + "Node name for S&R": "LayerUtility: GeminiV2" + }, + "widgets_values": [ + "gemini-2.0-flash", + 4096, + 0.5, + 200, + "en", + 0, + "fixed", + "You are creating a prompt for Stable Diffusion to generate an image.", + "Generate prompt: In image2, there is a girl riding on a dinosaur. Change this girl into the body shape and attire of image1. Only change the character's description, keeping everything else." + ], + "color": "rgba(38, 73, 116, 0.7)" + }, + { + "id": 23, + "type": "ShowText|pysssss", + "pos": [ + 689.0137939453125, + -16.73096466064453 + ], + "size": [ + 376.8567199707031, + 299.45538330078125 + ], + "flags": {}, + "order": 16, + "mode": 4, + "inputs": [ + { + "name": "text", + "type": "STRING", + "widget": { + "name": "text" + }, + "link": 41 + } + ], + "outputs": [ + { + "name": "STRING", + "shape": 6, + "type": "STRING", + "links": [ + 45 + ] + } + ], + "properties": { + "Node name for S&R": "ShowText|pysssss" + }, + "widgets_values": [ + "", + "A full shot of a woman riding a dinosaur through a lush jungle, sunlight filtering through the dense canopy, the woman is wearing a flowing, intricately embroidered light beige gown with delicate floral patterns and a sheer overlay, the dress has thin straps and a sweetheart neckline, emphasizing her elegant figure, her dark hair is styled in loose waves, cascading around her shoulders, she exudes confidence and grace, the dinosaur is vividly colored and realistically textured, blending seamlessly with the vibrant jungle backdrop, high resolution, photorealistic, cinematic lighting, depth of field, vibrant colors, intricate details, fantasy setting, magical realism.\n" + ] + }, + { + "id": 6, + "type": "CLIPTextEncode", + "pos": [ + 1139.0142822265625, + -426.7309265136719 + ], + "size": [ + 262.7925720214844, + 58 + ], + "flags": {}, + "order": 19, + "mode": 4, + "inputs": [ + { + "name": "clip", + "type": "CLIP", + "link": 3 + }, + { + "name": "text", + "type": "STRING", + "widget": { + "name": "text" + }, + "link": 33 + } + ], + "outputs": [ + { + "name": "CONDITIONING", + "type": "CONDITIONING", + "slot_index": 0, + "links": [ + 4 + ] + } + ], + "properties": { + "Node name for S&R": "CLIPTextEncode" + }, + "widgets_values": [ + "beautiful scenery nature glass bottle landscape, , purple galaxy bottle," + ] + }, + { + "id": 25, + "type": "CLIPTextEncode", + "pos": [ + 1109.0142822265625, + 23.26898765563965 + ], + "size": [ + 282.1186218261719, + 69.5741195678711 + ], + "flags": {}, + "order": 20, + "mode": 4, + "inputs": [ + { + "name": "clip", + "type": "CLIP", + "link": 44 + }, + { + "name": "text", + "type": "STRING", + "widget": { + "name": "text" + }, + "link": null + }, + { + "name": "text", + "type": "STRING", + "widget": { + "name": "text" + }, + "link": 45 + } + ], + "outputs": [ + { + "name": "CONDITIONING", + "type": "CONDITIONING", + "slot_index": 0, + "links": [ + 46 + ] + } + ], + "properties": { + "Node name for S&R": "CLIPTextEncode" + }, + "widgets_values": [ + "beautiful scenery nature glass bottle landscape, , purple galaxy bottle," + ] + }, + { + "id": 20, + "type": "KSampler", + "pos": [ + 1449.0142822265625, + 23.26898765563965 + ], + "size": [ + 315, + 262 + ], + "flags": {}, + "order": 23, + "mode": 4, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 34 + }, + { + "name": "positive", + "type": "CONDITIONING", + "link": 46 + }, + { + "name": "negative", + "type": "CONDITIONING", + "link": 36 + }, + { + "name": "latent_image", + "type": "LATENT", + "link": 37 + } + ], + "outputs": [ + { + "name": "LATENT", + "type": "LATENT", + "slot_index": 0, + "links": [ + 39 + ] + } + ], + "properties": { + "Node name for S&R": "KSampler" + }, + "widgets_values": [ + 0, + "fixed", + 20, + 1, + "euler", + "normal", + 1 + ] + }, + { + "id": 8, + "type": "VAEDecode", + "pos": [ + 1819.0142822265625, + -486.73095703125 + ], + "size": [ + 210, + 46 + ], + "flags": {}, + "order": 25, + "mode": 4, + "inputs": [ + { + "name": "samples", + "type": "LATENT", + "link": 7 + }, + { + "name": "vae", + "type": "VAE", + "link": 8 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "slot_index": 0, + "links": [ + 9 + ] + } + ], + "properties": { + "Node name for S&R": "VAEDecode" + }, + "widgets_values": [] + }, + { + "id": 9, + "type": "SaveImage", + "pos": [ + 2079.014404296875, + -496.73095703125 + ], + "size": [ + 442.9010314941406, + 293.555419921875 + ], + "flags": {}, + "order": 28, + "mode": 4, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 9 + } + ], + "outputs": [], + "properties": { + "Node name for S&R": "SaveImage" + }, + "widgets_values": [ + "ComfyUI" + ] + }, + { + "id": 22, + "type": "VAEDecode", + "pos": [ + 1819.0142822265625, + 43.26897430419922 + ], + "size": [ + 210, + 46 + ], + "flags": {}, + "order": 26, + "mode": 4, + "inputs": [ + { + "name": "samples", + "type": "LATENT", + "link": 39 + }, + { + "name": "vae", + "type": "VAE", + "link": 40 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "slot_index": 0, + "links": [ + 38 + ] + } + ], + "properties": { + "Node name for S&R": "VAEDecode" + }, + "widgets_values": [] + }, + { + "id": 21, + "type": "SaveImage", + "pos": [ + 2099.013916015625, + -6.730996608734131 + ], + "size": [ + 442.9010314941406, + 293.555419921875 + ], + "flags": {}, + "order": 29, + "mode": 4, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 38 + } + ], + "outputs": [], + "properties": { + "Node name for S&R": "SaveImage" + }, + "widgets_values": [ + "ComfyUI" + ] + }, + { + "id": 26, + "type": "SaveImage", + "pos": [ + 2099.013916015625, + 413.2691650390625 + ], + "size": [ + 442.9010314941406, + 293.555419921875 + ], + "flags": {}, + "order": 30, + "mode": 4, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 47 + } + ], + "outputs": [], + "properties": { + "Node name for S&R": "SaveImage" + }, + "widgets_values": [ + "ComfyUI" + ] + }, + { + "id": 28, + "type": "ShowText|pysssss", + "pos": [ + 689.0137939453125, + 403.2691650390625 + ], + "size": [ + 376.8567199707031, + 299.45538330078125 + ], + "flags": {}, + "order": 17, + "mode": 4, + "inputs": [ + { + "name": "text", + "type": "STRING", + "widget": { + "name": "text" + }, + "link": 50 + } + ], + "outputs": [ + { + "name": "STRING", + "shape": 6, + "type": "STRING", + "links": [ + 52 + ] + } + ], + "properties": { + "Node name for S&R": "ShowText|pysssss" + }, + "widgets_values": [ + "", + "Generate a photorealistic image capturing an unexpected scene: a graceful, slender adult woman with flowing long dark wavy hair confidently riding astride a large, friendly-looking green T-Rex-style dinosaur. She is dressed in a stunning, highly detailed, floor-length beige evening gown adorned with intricate gold embroidery and sparkling sequins. The gown features delicate spaghetti straps, a flattering sweetheart neckline, and a diaphanous sheer overlay skirt that billows slightly, contrasting sharply with the rugged environment. They traverse a narrow dirt path winding through an incredibly lush, vibrant jungle environment filled with dense tropical foliage, towering ancient trees, and exotic plants under a bright sky. Bright, warm sunlight dramatically filters through the thick canopy above, casting dynamic sunbeams and dappled light onto the path and subjects. Focus on the contrast between the woman's formal elegance and the prehistoric, wild setting. Maintain high detail in textures – the gown's delicate fabric, the dinosaur's detailed scales, the jungle leaves. Cinematic lighting, sharp focus, fantasy art style, adventure theme, 8k resolution." + ] + }, + { + "id": 29, + "type": "CLIPTextEncode", + "pos": [ + 1109.0142822265625, + 443.2691955566406 + ], + "size": [ + 282.1186218261719, + 69.5741195678711 + ], + "flags": {}, + "order": 21, + "mode": 4, + "inputs": [ + { + "name": "clip", + "type": "CLIP", + "link": 51 + }, + { + "name": "text", + "type": "STRING", + "widget": { + "name": "text" + }, + "link": null + }, + { + "name": "text", + "type": "STRING", + "widget": { + "name": "text" + }, + "link": 52 + } + ], + "outputs": [ + { + "name": "CONDITIONING", + "type": "CONDITIONING", + "slot_index": 0, + "links": [ + 54 + ] + } + ], + "properties": { + "Node name for S&R": "CLIPTextEncode" + }, + "widgets_values": [ + "beautiful scenery nature glass bottle landscape, , purple galaxy bottle," + ] + }, + { + "id": 30, + "type": "KSampler", + "pos": [ + 1449.0142822265625, + 443.2691955566406 + ], + "size": [ + 315, + 262 + ], + "flags": {}, + "order": 24, + "mode": 4, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 53 + }, + { + "name": "positive", + "type": "CONDITIONING", + "link": 54 + }, + { + "name": "negative", + "type": "CONDITIONING", + "link": 55 + }, + { + "name": "latent_image", + "type": "LATENT", + "link": 56 + } + ], + "outputs": [ + { + "name": "LATENT", + "type": "LATENT", + "slot_index": 0, + "links": [ + 57 + ] + } + ], + "properties": { + "Node name for S&R": "KSampler" + }, + "widgets_values": [ + 0, + "fixed", + 20, + 1, + "euler", + "normal", + 1 + ] + }, + { + "id": 31, + "type": "VAEDecode", + "pos": [ + 1819.0142822265625, + 463.2691650390625 + ], + "size": [ + 210, + 46 + ], + "flags": {}, + "order": 27, + "mode": 4, + "inputs": [ + { + "name": "samples", + "type": "LATENT", + "link": 57 + }, + { + "name": "vae", + "type": "VAE", + "link": 58 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "slot_index": 0, + "links": [ + 47 + ] + } + ], + "properties": { + "Node name for S&R": "VAEDecode" + }, + "widgets_values": [] + }, + { + "id": 27, + "type": "LayerUtility: GeminiV2", + "pos": [ + 269.0139465332031, + 403.2691650390625 + ], + "size": [ + 403.1999816894531, + 300 + ], + "flags": {}, + "order": 11, + "mode": 4, + "inputs": [ + { + "name": "image_1", + "shape": 7, + "type": "IMAGE", + "link": 48 + }, + { + "name": "image_2", + "shape": 7, + "type": "IMAGE", + "link": 49 + } + ], + "outputs": [ + { + "name": "text", + "shape": 6, + "type": "STRING", + "links": [ + 50 + ] + } + ], + "properties": { + "Node name for S&R": "LayerUtility: GeminiV2" + }, + "widgets_values": [ + "gemini-2.5-pro-exp-03-25", + 4096, + 0.5, + 200, + "en", + 0, + "fixed", + "You are creating a prompt for Stable Diffusion to generate an image.", + "Generate prompt: In image2, there is a girl riding on a dinosaur. Change this girl into the body shape and attire of image1. Only change the character's description, keeping everything else." + ], + "color": "rgba(38, 73, 116, 0.7)" + }, + { + "id": 7, + "type": "CLIPTextEncode", + "pos": [ + -533.4188842773438, + -272.3014831542969 + ], + "size": [ + 377.7937927246094, + 88 + ], + "flags": {}, + "order": 6, + "mode": 4, + "inputs": [ + { + "name": "clip", + "type": "CLIP", + "link": 5 + } + ], + "outputs": [ + { + "name": "CONDITIONING", + "type": "CONDITIONING", + "slot_index": 0, + "links": [ + 6, + 36, + 55 + ] + } + ], + "properties": { + "Node name for S&R": "CLIPTextEncode" + }, + "widgets_values": [ + "text, watermark" + ] + }, + { + "id": 5, + "type": "EmptyLatentImage", + "pos": [ + -514.9091186523438, + -124.45889282226562 + ], + "size": [ + 315, + 106 + ], + "flags": {}, + "order": 0, + "mode": 4, + "inputs": [], + "outputs": [ + { + "name": "LATENT", + "type": "LATENT", + "slot_index": 0, + "links": [ + 25, + 37, + 56 + ] + } + ], + "properties": { + "Node name for S&R": "EmptyLatentImage" + }, + "widgets_values": [ + 1280, + 720, + 1 + ] + }, + { + "id": 19, + "type": "LayerUtility: GeminiV2", + "pos": [ + 259.013916015625, + -486.73095703125 + ], + "size": [ + 403.1999816894531, + 300 + ], + "flags": {}, + "order": 9, + "mode": 4, + "inputs": [ + { + "name": "image_1", + "shape": 7, + "type": "IMAGE", + "link": 30 + }, + { + "name": "image_2", + "shape": 7, + "type": "IMAGE", + "link": 31 + } + ], + "outputs": [ + { + "name": "text", + "shape": 6, + "type": "STRING", + "links": [ + 32 + ] + } + ], + "properties": { + "Node name for S&R": "LayerUtility: GeminiV2" + }, + "widgets_values": [ + "gemini-2.0-flash-lite", + 4096, + 0.5, + 200, + "en", + 0, + "fixed", + "You are creating a prompt for Stable Diffusion to generate an image.", + "Generate prompt: In image2, there is a girl riding on a dinosaur. Change this girl into the body shape and attire of image1. Only change the character's description, keeping everything else." + ], + "color": "rgba(38, 73, 116, 0.7)" + }, + { + "id": 76, + "type": "PreviewImage", + "pos": [ + 673.2804565429688, + 952.0642700195312 + ], + "size": [ + 320.7438049316406, + 258 + ], + "flags": {}, + "order": 14, + "mode": 4, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 127 + } + ], + "outputs": [], + "properties": { + "Node name for S&R": "PreviewImage" + }, + "widgets_values": [] + }, + { + "id": 45, + "type": "PreviewImage", + "pos": [ + 677.2026977539062, + 1320.571533203125 + ], + "size": [ + 315.5809326171875, + 263.8492431640625 + ], + "flags": {}, + "order": 13, + "mode": 4, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 88 + } + ], + "outputs": [], + "properties": { + "Node name for S&R": "PreviewImage" + }, + "widgets_values": [] + }, + { + "id": 75, + "type": "LayerMask: ObjectDetectorGemini", + "pos": [ + 201.73040771484375, + 1041.1883544921875 + ], + "size": [ + 392.19921875, + 104.36209106445312 + ], + "flags": {}, + "order": 8, + "mode": 4, + "inputs": [ + { + "name": "image", + "type": "IMAGE", + "link": 126 + } + ], + "outputs": [ + { + "name": "bboxes", + "type": "BBOXES", + "links": null + }, + { + "name": "preview", + "type": "IMAGE", + "links": [ + 127 + ] + } + ], + "properties": { + "Node name for S&R": "LayerMask: ObjectDetectorGemini" + }, + "widgets_values": [ + "gemini-1.5-pro", + "left arm of the fox" + ], + "color": "rgba(27, 80, 119, 0.7)" + }, + { + "id": 44, + "type": "LayerMask: ObjectDetectorGeminiV2", + "pos": [ + 198.4856719970703, + 1227.0968017578125 + ], + "size": [ + 396.632080078125, + 105.54935455322266 + ], + "flags": {}, + "order": 7, + "mode": 4, + "inputs": [ + { + "name": "image", + "type": "IMAGE", + "link": 87 + } + ], + "outputs": [ + { + "name": "bboxes", + "type": "BBOXES", + "links": [] + }, + { + "name": "preview", + "type": "IMAGE", + "links": [ + 88 + ] + } + ], + "properties": { + "Node name for S&R": "LayerMask: ObjectDetectorGeminiV2" + }, + "widgets_values": [ + "gemini-2.5-pro-exp-03-25", + "left arm of the fox" + ], + "color": "rgba(27, 80, 119, 0.7)" + }, + { + "id": 3, + "type": "KSampler", + "pos": [ + 1469.0142822265625, + -506.73095703125 + ], + "size": [ + 315, + 262 + ], + "flags": {}, + "order": 22, + "mode": 4, + "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": 25 + } + ], + "outputs": [ + { + "name": "LATENT", + "type": "LATENT", + "slot_index": 0, + "links": [ + 7 + ] + } + ], + "properties": { + "Node name for S&R": "KSampler" + }, + "widgets_values": [ + 39, + "fixed", + 20, + 1, + "euler", + "normal", + 1 + ] + }, + { + "id": 13, + "type": "ShowText|pysssss", + "pos": [ + 699.0137939453125, + -486.73095703125 + ], + "size": [ + 413.1211853027344, + 285.5541076660156 + ], + "flags": {}, + "order": 15, + "mode": 4, + "inputs": [ + { + "name": "text", + "type": "STRING", + "widget": { + "name": "text" + }, + "link": 32 + } + ], + "outputs": [ + { + "name": "STRING", + "shape": 6, + "type": "STRING", + "links": [ + 33 + ] + } + ], + "properties": { + "Node name for S&R": "ShowText|pysssss" + }, + "widgets_values": [ + "", + "A beautiful woman with long, flowing dark hair, wearing a stunning, elegant, and intricately designed beige gown with delicate floral embroidery. The dress features a low-cut neckline, a fitted bodice, and a flowing skirt with a sheer overlay, creating a graceful and ethereal look. She has a slender figure and is posed in a way that emphasizes the beauty of the dress, with her arms slightly outstretched. The background is a lush, vibrant jungle scene with sunlight filtering through the trees, and a dinosaur walking on the path. The woman is riding on the dinosaur, maintaining the original composition and background of the image, but with the character's appearance transformed. The overall style is photorealistic, with a focus on detail and a sense of fantasy.\n" + ] + }, + { + "id": 4, + "type": "CheckpointLoaderSimple", + "pos": [ + -543.4984130859375, + -445.49652099609375 + ], + "size": [ + 381.9781799316406, + 98 + ], + "flags": {}, + "order": 1, + "mode": 4, + "inputs": [], + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "slot_index": 0, + "links": [ + 1, + 34, + 53 + ] + }, + { + "name": "CLIP", + "type": "CLIP", + "slot_index": 1, + "links": [ + 3, + 5, + 44, + 51 + ] + }, + { + "name": "VAE", + "type": "VAE", + "slot_index": 2, + "links": [ + 8, + 40, + 58 + ] + } + ], + "properties": { + "Node name for S&R": "CheckpointLoaderSimple" + }, + "widgets_values": [ + "FLUX\\flux1-dev-fp8.safetensors" + ] + }, + { + "id": 11, + "type": "LoadImage", + "pos": [ + -706.8624877929688, + 372.4265441894531 + ], + "size": [ + 315, + 314 + ], + "flags": {}, + "order": 2, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "slot_index": 0, + "links": [ + 31, + 43, + 49, + 87, + 126 + ] + }, + { + "name": "MASK", + "type": "MASK", + "links": null + } + ], + "properties": { + "Node name for S&R": "LoadImage" + }, + "widgets_values": [ + "girl_dino_1024.png", + "image" + ] + }, + { + "id": 12, + "type": "LoadImage", + "pos": [ + -725.3201904296875, + 819.2488403320312 + ], + "size": [ + 315, + 314 + ], + "flags": {}, + "order": 3, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "slot_index": 0, + "links": [ + 30, + 42, + 48 + ] + }, + { + "name": "MASK", + "type": "MASK", + "links": null + } + ], + "properties": { + "Node name for S&R": "LoadImage" + }, + "widgets_values": [ + "768x1344_dress.png", + "image" + ] + }, + { + "id": 81, + "type": "LoadImage", + "pos": [ + -1269.763427734375, + 2275.29443359375 + ], + "size": [ + 315, + 314 + ], + "flags": {}, + "order": 4, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "slot_index": 0, + "links": [ + 137 + ] + }, + { + "name": "MASK", + "type": "MASK", + "links": null + } + ], + "properties": { + "Node name for S&R": "LoadImage" + }, + "widgets_values": [ + "girl_dino_1024.png", + "image", + "" + ] + }, + { + "id": 84, + "type": "LoadImage", + "pos": [ + -1268.330322265625, + 2647.683349609375 + ], + "size": [ + 315, + 314 + ], + "flags": {}, + "order": 5, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 141 + ] + }, + { + "name": "MASK", + "type": "MASK", + "links": null + } + ], + "properties": { + "Node name for S&R": "LoadImage" + }, + "widgets_values": [ + "768x1344_dress.png", + "image", + "" + ] + }, + { + "id": 77, + "type": "LayerUtility: GeminiImageEdit", + "pos": [ + -861.7073364257812, + 2517.60009765625 + ], + "size": [ + 490.666748046875, + 224 + ], + "flags": {}, + "order": 12, + "mode": 0, + "inputs": [ + { + "name": "image", + "type": "IMAGE", + "link": 137 + }, + { + "name": "image_2", + "shape": 7, + "type": "IMAGE", + "link": 141 + }, + { + "name": "image_3", + "shape": 7, + "type": "IMAGE", + "link": null + } + ], + "outputs": [ + { + "name": "image", + "type": "IMAGE", + "links": [ + 134 + ] + }, + { + "name": "text", + "type": "STRING", + "links": [] + } + ], + "properties": { + "Node name for S&R": "LayerUtility: GeminiImageEdit" + }, + "widgets_values": [ + "gemini-2.0-flash-exp-image-generation", + 0.5, + 1102846641, + "randomize", + "Let the girl wear the dress shown in the second image" + ], + "color": "rgba(38, 73, 116, 0.7)" + }, + { + "id": 78, + "type": "PreviewImage", + "pos": [ + -275.3845520019531, + 2320.55615234375 + ], + "size": [ + 516.1419067382812, + 543.9136962890625 + ], + "flags": {}, + "order": 18, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 134 + } + ], + "outputs": [], + "properties": { + "Node name for S&R": "PreviewImage" + }, + "widgets_values": [ + "" + ] + } + ], + "links": [ + [ + 1, + 4, + 0, + 3, + 0, + "MODEL" + ], + [ + 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" + ], + [ + 9, + 8, + 0, + 9, + 0, + "IMAGE" + ], + [ + 25, + 5, + 0, + 3, + 3, + "LATENT" + ], + [ + 30, + 12, + 0, + 19, + 0, + "IMAGE" + ], + [ + 31, + 11, + 0, + 19, + 1, + "IMAGE" + ], + [ + 32, + 19, + 0, + 13, + 0, + "STRING" + ], + [ + 33, + 13, + 0, + 6, + 1, + "STRING" + ], + [ + 34, + 4, + 0, + 20, + 0, + "MODEL" + ], + [ + 36, + 7, + 0, + 20, + 2, + "CONDITIONING" + ], + [ + 37, + 5, + 0, + 20, + 3, + "LATENT" + ], + [ + 38, + 22, + 0, + 21, + 0, + "IMAGE" + ], + [ + 39, + 20, + 0, + 22, + 0, + "LATENT" + ], + [ + 40, + 4, + 2, + 22, + 1, + "VAE" + ], + [ + 41, + 24, + 0, + 23, + 0, + "STRING" + ], + [ + 42, + 12, + 0, + 24, + 0, + "IMAGE" + ], + [ + 43, + 11, + 0, + 24, + 1, + "IMAGE" + ], + [ + 44, + 4, + 1, + 25, + 0, + "CLIP" + ], + [ + 45, + 23, + 0, + 25, + 2, + "STRING" + ], + [ + 46, + 25, + 0, + 20, + 1, + "CONDITIONING" + ], + [ + 47, + 31, + 0, + 26, + 0, + "IMAGE" + ], + [ + 48, + 12, + 0, + 27, + 0, + "IMAGE" + ], + [ + 49, + 11, + 0, + 27, + 1, + "IMAGE" + ], + [ + 50, + 27, + 0, + 28, + 0, + "STRING" + ], + [ + 51, + 4, + 1, + 29, + 0, + "CLIP" + ], + [ + 52, + 28, + 0, + 29, + 2, + "STRING" + ], + [ + 53, + 4, + 0, + 30, + 0, + "MODEL" + ], + [ + 54, + 29, + 0, + 30, + 1, + "CONDITIONING" + ], + [ + 55, + 7, + 0, + 30, + 2, + "CONDITIONING" + ], + [ + 56, + 5, + 0, + 30, + 3, + "LATENT" + ], + [ + 57, + 30, + 0, + 31, + 0, + "LATENT" + ], + [ + 58, + 4, + 2, + 31, + 1, + "VAE" + ], + [ + 87, + 11, + 0, + 44, + 0, + "IMAGE" + ], + [ + 88, + 44, + 1, + 45, + 0, + "IMAGE" + ], + [ + 126, + 11, + 0, + 75, + 0, + "IMAGE" + ], + [ + 127, + 75, + 1, + 76, + 0, + "IMAGE" + ], + [ + 134, + 77, + 0, + 78, + 0, + "IMAGE" + ], + [ + 137, + 81, + 0, + 77, + 0, + "IMAGE" + ], + [ + 141, + 84, + 0, + 77, + 1, + "IMAGE" + ] + ], + "groups": [], + "config": {}, + "extra": { + "ds": { + "scale": 0.8264462809917354, + "offset": [ + 1984.9666976182002, + -1894.771297031591 + ] + } + }, + "version": 0.4 +} \ No newline at end of file