├── .github └── workflows │ └── publish.yml ├── .gitignore ├── LICENSE ├── README.md ├── __init__.py ├── example └── 服饰一致性.png ├── pyproject.toml ├── reduxPrompt.py ├── requirements.txt └── 服饰一致性.png /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish to Comfy registry 2 | on: 3 | workflow_dispatch: 4 | push: 5 | branches: 6 | - main 7 | - master 8 | paths: 9 | - "pyproject.toml" 10 | 11 | jobs: 12 | publish-node: 13 | name: Publish Custom Node to registry 14 | runs-on: ubuntu-latest 15 | # if this is a forked repository. Skipping the workflow. 16 | if: github.event.repository.fork == false 17 | steps: 18 | - name: Check out code 19 | uses: actions/checkout@v4 20 | - name: Publish Custom Node 21 | uses: Comfy-Org/publish-node-action@main 22 | with: 23 | ## Add your own personal access token to your Github Repository secrets and reference it here. 24 | personal_access_token: ${{ secrets.REGISTRY_ACCESS_TOKEN }} 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | __pycache__/__init__.cpython-311.pyc 3 | __pycache__/__init__.cpython-311.pyc 4 | __pycache__/__init__.cpython-311.pyc 5 | __pycache__/reduxPrompt.cpython-311.pyc 6 | /__pycache__ 7 | 项目说明.txt 8 | 项目说明.txt 9 | __pycache__/__init__.cpython-311.pyc 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Redux Style with Prompt Control 2 | 3 | A ComfyUI custom node that provides fine-grained control over style transfer using Redux style models. 4 | 5 | 一个 ComfyUI 自定义节点,提供使用 Redux 风格模型进行精细风格迁移控制。 6 | 7 | 8 | 9 | https://github.com/user-attachments/assets/d6cf3b71-0221-4804-a757-e43feab0850f 10 | 11 | ![alt text](服饰一致性.png) 12 | 13 | ## Features / 功能特点 14 | 15 | - Combine text prompts with reference image styles 16 | - Adjustable influence for both prompts and reference images 17 | - Flexible style detail control (27×27 to 1×1 grid) 18 | - Flexible image processing modes 19 | - Support for masked regions 20 | - Multiple interpolation methods 21 | 22 | --- 23 | 24 | - 结合文本提示词和参考图像风格 25 | - 可调节的提示词和参考图像影响力 26 | - 灵活的风格细节控制(27×27 到 1×1 网格) 27 | - 灵活的图像处理模式 28 | - 支持蒙版区域 29 | - 多种插值方法 30 | 31 | ## Parameters / 参数说明 32 | 33 | ### Required Inputs / 必需输入 34 | - `conditioning`: Original prompt input / 原始提示词输入 35 | - `style_model`: Redux style model / Redux 风格模型 36 | - `clip_vision`: CLIP vision encoder / CLIP 视觉编码器 37 | - `reference_image`: Style source image / 风格来源图像 38 | - `prompt_influence`: Prompt strength (1.0=normal) / 提示词强度 (1.0=正常) 39 | - `reference_influence`: Image influence (1.0=normal) / 图像影响 (1.0=正常) 40 | - `style_grid_size`: Style detail level (1=27×27 strongest, 14=1×1 weakest) / 风格细节等级 (1=27×27最强, 14=1×1最弱) 41 | - `interpolation_mode`: Token interpolation method / Token插值方法 42 | - `image_processing_mode`: Image processing mode / 图像处理模式 43 | - `center crop`: Square center crop / 正方形中心裁剪 44 | - `keep aspect ratio`: Maintain original ratio / 保持原始比例 45 | - `autocrop with mask`: Automatic crop using mask / 使用蒙版自动裁剪 46 | 47 | ### Optional Inputs / 可选输入 48 | - `mask`: Optional mask for local control / 用于局部控制的可选蒙版 49 | - `autocrop_padding`: Padding pixels for autocrop (0-256) / 自动裁剪的边距像素 (0-256) 50 | 51 | ## Installation / 安装 52 | 53 | ### Method 1: Install via ComfyUI Manager (Recommended) 54 | ### 方法一:通过 ComfyUI Manager 安装(推荐) 55 | 56 | 1. Install [ComfyUI Manager](https://github.com/ltdrdata/ComfyUI-Manager) if you haven't 57 | 如果还没有安装 [ComfyUI Manager](https://github.com/ltdrdata/ComfyUI-Manager),请先安装 58 | 59 | 2. Open ComfyUI, go to Manager tab 60 | 打开 ComfyUI,进入 Manager 标签页 61 | 62 | 3. Search for "Redux Prompt" and install 63 | 搜索 "Redux Prompt" 并安装 64 | 65 | ### Method 2: Manual Installation 66 | ### 方法二:手动安装 67 | 68 | 1. Clone this repository to your ComfyUI custom nodes directory: 69 | 将此仓库克隆到你的 ComfyUI 自定义节点目录: 70 | 71 | ```bash 72 | cd ComfyUI/custom_nodes 73 | git clone https://github.com/CY-CHENYUE/ComfyUI-Redux-Prompt.git 74 | ``` 75 | 76 | 2. Restart ComfyUI 77 | 重启 ComfyUI 78 | 79 | ## Usage Example / 使用示例 80 | 81 | 1. Add the "Redux Style with Prompt Control" node to your workflow 82 | 将 "Redux Style with Prompt Control" 节点添加到你的工作流程中 83 | 84 | 2. Connect required inputs: 85 | 连接必需的输入: 86 | - Text prompt conditioning 87 | - Redux style model 88 | - CLIP Vision model 89 | - Reference image 90 | 91 | 3. Adjust parameters as needed: 92 | 根据需要调整参数: 93 | - Set style grid size (1-14) for desired detail level 94 | - Adjust prompt and reference influence 95 | - Choose appropriate interpolation mode 96 | - Select image processing mode 97 | 98 | 4. Connect the output to your image generation pipeline 99 | 将输出连接到你的图像生成管线 100 | 101 | ## Notes / 注意事项 102 | 103 | - Higher `prompt_influence` values will emphasize the text prompt 104 | 较高的 `prompt_influence` 值会强调文本提示词 105 | - Higher `reference_influence` values will emphasize the reference image style 106 | 较高的 `reference_influence` 值会强调参考图像风格 107 | - Lower style grid size values (closer to 1) provide stronger, more detailed style transfer 108 | 较低的风格网格值(接近1)提供更强、更详细的风格迁移 109 | - Higher style grid size values (closer to 14) provide lighter, more general style transfer 110 | 较高的风格网格值(接近14)提供更轻微、更概括的风格迁移 111 | - Different interpolation modes can affect the style transfer quality 112 | 不同的插值模式会影响风格迁移的质量 113 | - Mask input is only used when `autocrop with mask` mode is selected 114 | 蒙版输入仅在选择 `autocrop with mask` 模式时使用 115 | 116 | -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from .reduxPrompt import NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS 4 | 5 | NODE_CLASS_MAPPINGS = { 6 | **NODE_CLASS_MAPPINGS 7 | } 8 | 9 | NODE_DISPLAY_NAME_MAPPINGS = { 10 | **NODE_DISPLAY_NAME_MAPPINGS 11 | } 12 | 13 | __all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS'] 14 | 15 | -------------------------------------------------------------------------------- /example/服饰一致性.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CY-CHENYUE/ComfyUI-Redux-Prompt/50ebbfdce9cf42788fbcf661d61b5a163e462856/example/服饰一致性.png -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "comfyui-redux-prompt" 3 | description = "A ComfyUI custom node that provides fine-grained control over style transfer using Redux style models." 4 | version = "1.0.2" 5 | license = {file = "LICENSE"} 6 | dependencies = ["numpy", "torch"] 7 | 8 | [project.urls] 9 | Repository = "https://github.com/CY-CHENYUE/ComfyUI-Redux-Prompt" 10 | # Used by Comfy Registry https://comfyregistry.org 11 | 12 | [tool.comfy] 13 | PublisherId = "cychenyue" 14 | DisplayName = "ComfyUI-Redux-Prompt" 15 | Icon = "" 16 | -------------------------------------------------------------------------------- /reduxPrompt.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import torch 3 | import comfy 4 | import folder_paths 5 | import nodes 6 | 7 | class ReduxPromptStyler: 8 | @classmethod 9 | def INPUT_TYPES(s): 10 | return { 11 | "required": { 12 | # 原始的提示词条件输入 13 | "conditioning": ("CONDITIONING", ), 14 | # Redux 风格模型 15 | "style_model": ("STYLE_MODEL", ), 16 | # CLIP 视觉编码器 17 | "clip_vision": ("CLIP_VISION", ), 18 | # 参考图像输入 19 | "reference_image": ("IMAGE",), 20 | 21 | # 控制提示词的影响强度 (1.0=正常强度, <1.0减弱, >1.0增强) 22 | "prompt_influence": ("FLOAT", { 23 | "default": 1.0, 24 | "min": 0.1, 25 | "max": 2.0, 26 | "step": 0.1 27 | }), 28 | 29 | # 控制参考图像的影响强度 (1.0=正常强度, <1.0减弱, >1.0增强) 30 | "reference_influence": ("FLOAT", { 31 | "default": 1.0, 32 | "min": 0.1, 33 | "max": 2.0, 34 | "step": 0.1 35 | }), 36 | 37 | # 控制风格tokens的网格大小 38 | "style_grid_size": ("INT", { 39 | "default": 9, # 默认值改为9 (对应5x5网格) 40 | "min": 1, # 第1个选项 41 | "max": 14, # 第14个选项 42 | "step": 1, # 每次调整1步 43 | "display": "slider", # 显示为滑块 44 | }), 45 | 46 | # 插值方法择 47 | "interpolation_mode": (["bicubic", "bilinear", "nearest", "area"], { 48 | "default": "bicubic", 49 | }), 50 | 51 | # 参考图像的处理模式 52 | "image_processing_mode": ([ 53 | "center crop (square)", # 中心裁剪为正方形 54 | "keep aspect ratio", # 保持原始宽高比 55 | "autocrop with mask" # 根据蒙版自动裁剪 56 | ], { 57 | "default": "center crop (square)" 58 | }), 59 | }, 60 | "optional": { 61 | # 可选的蒙版输入,用于局部控制或自动裁剪 62 | "mask": ("MASK", ), 63 | 64 | # 使用自动裁剪时的边距像素值 65 | "autocrop_padding": ("INT", { 66 | "default": 8, # 默认32像素边距 67 | "min": 0, # 无边距 68 | "max": 256, # 最大256像素边距 69 | "step": 8, 70 | "display_step": 8, 71 | "display": "slider" 72 | }) 73 | } 74 | } 75 | 76 | RETURN_TYPES = ("CONDITIONING", "IMAGE") 77 | FUNCTION = "apply_style_with_prompt" 78 | CATEGORY = "reduxPrompt" 79 | 80 | # 添加节点说明 81 | DESCRIPTION = """Redux Style with Prompt Control 82 | 83 | [English] 84 | - conditioning: Original prompt input 85 | - style_model: Redux style model 86 | - clip_vision: CLIP vision encoder 87 | - reference_image: Style source image 88 | - prompt_influence: Prompt strength (1.0=normal) 89 | - reference_influence: Image influence (1.0=normal) 90 | - style_grid_size: Style detail level (1=strongest 27x27, 14=weakest 1x1) 91 | - interpolation_mode: Token interpolation method 92 | - image_processing_mode: Image mode (crop/aspect/mask) 93 | - mask: Optional mask 94 | - autocrop_padding: Cropping padding (0-256) 95 | 96 | [中文] 97 | - conditioning: 原始提示词输入 98 | - style_model: Redux 风格模型 99 | - clip_vision: CLIP 视觉编码器 100 | - reference_image: 风格参考图像 101 | - prompt_influence: 提示词强度 (1.0=正常) 102 | - reference_influence: 图像影响 (1.0=正常) 103 | - style_grid_size: 风格细节等级 (1=最强 27x27, 14=最弱 1x1) 104 | - interpolation_mode: Token插值方法 105 | - image_processing_mode: 图像模式 (裁剪/比例/蒙版) 106 | - mask: 可选蒙版 107 | - autocrop_padding: 裁剪边距 (0-256)""" 108 | 109 | def prepare_image(self, image, mask=None, mode="center crop (square)", 110 | padding=32, desired_size=384): 111 | """ 112 | 预处理参考图像到指定大小和格式 113 | 114 | Args: 115 | image: 输入图像 tensor [B, H, W, C] 116 | mask: 可选的蒙版 tensor 117 | mode: 图像处理模式 118 | padding: 自动裁剪时的边距像素值 119 | desired_size: 目标图像大小 (默认 384x384) 120 | 121 | Returns: 122 | 处理后的图像和蒙版 123 | """ 124 | B, H, W, C = image.shape 125 | 126 | if mode == "center crop (square)": 127 | # 计算裁剪位置(居中裁剪) 128 | crop_size = min(H, W) 129 | x = max(0, (W - crop_size) // 2) 130 | y = max(0, (H - crop_size) // 2) 131 | 132 | # 执行裁剪操作,确保不超出边界 133 | end_x = x + crop_size 134 | end_y = y + crop_size 135 | image = image[:, y:end_y, x:end_x, :] 136 | 137 | # 调整图像大小到 desired_size 138 | image = torch.nn.functional.interpolate( 139 | image.transpose(-1, 1), 140 | size=(desired_size, desired_size), 141 | mode="bicubic", 142 | antialias=True, 143 | align_corners=True 144 | ).transpose(1, -1) 145 | 146 | elif mode == "keep aspect ratio": 147 | # Resize while keeping aspect ratio 148 | image = torch.nn.functional.interpolate( 149 | image.transpose(-1, 1), 150 | size=(W, H), 151 | mode="bicubic", 152 | antialias=True, 153 | align_corners=True 154 | ).transpose(1, -1) 155 | 156 | elif mode == "autocrop with mask" and mask is not None: 157 | # 获取mask中非零区域的边界框坐标 158 | mask_np = mask.squeeze(0).cpu().numpy() 159 | nonzero_indices = np.nonzero(mask_np) 160 | if len(nonzero_indices[0]) == 0: 161 | # 如果mask为空,回退到center crop模式 162 | return self.prepare_image(image, mode="center crop (square)", 163 | desired_size=desired_size) 164 | 165 | # 获取边界框坐标 166 | min_y, max_y = np.min(nonzero_indices[0]), np.max(nonzero_indices[0]) 167 | min_x, max_x = np.min(nonzero_indices[1]), np.max(nonzero_indices[1]) 168 | 169 | # 计算mask区域的宽度和高度 170 | mask_width = max_x - min_x + 1 171 | mask_height = max_y - min_y + 1 172 | 173 | # 直接使用像素值作为padding 174 | padding_x = padding 175 | padding_y = padding 176 | 177 | # 计算目标尺寸 178 | target_width = mask_width + (2 * padding_x) 179 | target_height = mask_height + (2 * padding_y) 180 | 181 | # 确保尺寸是8的倍数 182 | target_width = ((target_width + 7) // 8) * 8 183 | target_height = ((target_height + 7) // 8) * 8 184 | 185 | # 计算中心点 186 | center_x = (min_x + max_x) // 2 187 | center_y = (min_y + max_y) // 2 188 | 189 | # 计算裁剪区域 190 | crop_x = center_x - (target_width // 2) 191 | crop_y = center_y - (target_height // 2) 192 | 193 | # 确保裁剪区域在图像范围内 194 | crop_x = max(0, min(crop_x, W - target_width)) 195 | crop_y = max(0, min(crop_y, H - target_height)) 196 | 197 | # 执行裁剪 198 | image = image[:, crop_y:crop_y+target_height, crop_x:crop_x+target_width, :] 199 | 200 | # 调整到目标尺寸,保持宽高比 201 | aspect_ratio = target_width / target_height 202 | if aspect_ratio > 1: # 宽大于高 203 | new_height = desired_size 204 | new_width = int(desired_size * aspect_ratio) 205 | else: # 高大于宽 206 | new_width = desired_size 207 | new_height = int(desired_size / aspect_ratio) 208 | 209 | # 确保尺寸是8的倍数 210 | new_width = ((new_width + 7) // 8) * 8 211 | new_height = ((new_height + 7) // 8) * 8 212 | 213 | # 调整图像大小 - 修正通道顺序 214 | image = image.permute(0, 3, 1, 2) # [B, H, W, C] -> [B, C, H, W] 215 | image = torch.nn.functional.interpolate( 216 | image, 217 | size=(new_height, new_width), 218 | mode="bicubic", 219 | antialias=True, 220 | align_corners=True 221 | ) 222 | image = image.permute(0, 2, 3, 1) # [B, C, H, W] -> [B, H, W, C] 223 | 224 | return image 225 | 226 | 227 | 228 | def apply_style_with_prompt(self, clip_vision, reference_image, style_model, conditioning, 229 | prompt_influence, reference_influence, style_grid_size, 230 | interpolation_mode, image_processing_mode, 231 | mask=None, autocrop_padding=32): 232 | """ 233 | 将参考图像的风格��用到提示词条件中 234 | 235 | Args: 236 | clip_vision: CLIP视觉编码器 237 | reference_image: 参考图像 238 | style_model: Redux风格模型 239 | conditioning: 原始提示词条件 240 | prompt_influence: 提示词影响强度 241 | reference_influence: 参考图影响强度 242 | style_grid_size: 风格token网格大小 243 | interpolation_mode: token缩减插值法 244 | image_processing_mode: 图像处理模式 245 | mask: 可选的蒙版 246 | autocrop_padding: 自动裁剪边距 247 | 248 | Returns: 249 | tuple: (处理后的条, 处理后图像) 250 | """ 251 | # 将文字选项转换为对应的数值 252 | reduction_map = { 253 | "strongest style (27x27)": 1, 254 | "strong style (9x9)": 3, 255 | "balanced style (5x5)": 5, 256 | "weak style (3x3)": 9, 257 | "weakest style (1x1)": 27, 258 | "auto balance": None # 使用 None 表示自动平衡逻辑 259 | } 260 | target_size = style_grid_size 261 | reduction_factor = target_size 262 | 263 | # 预处理参考图像到指定大小和格式 264 | processed_image = self.prepare_image( 265 | reference_image, 266 | mask=mask, # 传入蒙版参数 267 | mode=image_processing_mode, # 使���函数参数中的图像处理模式 268 | padding=autocrop_padding, # 使用函数参数中的自动裁剪边距 269 | desired_size=384 # 可以根据需要修改目尺寸 270 | ) 271 | 272 | # 获取 CLIP 视觉输出 273 | clip_vision_output = clip_vision.encode_image(processed_image) 274 | 275 | # 获取风格条件 (27x27 patches) 276 | cond = style_model.get_cond(clip_vision_output) 277 | cond = cond.flatten(start_dim=0, end_dim=1).unsqueeze(dim=0) 278 | 279 | # 获取提示词的 tokens 数量 280 | prompt_tokens = conditioning[0][0].shape[1] # 获取第一个条件的 token 数量 281 | 282 | # 计算目标网格大小(从滑块值转换到实际的网格大小) 283 | grid_sizes = [27, 25, 23, 21, 19, 17, 15, 13, 11, 9, 7, 5, 3, 1] 284 | target_size = grid_sizes[style_grid_size - 1] # 因为滑块值从1开始 285 | 286 | # 应用下采样来减少 tokens 数量 287 | b, t, h = cond.shape 288 | m = int(np.sqrt(t)) 289 | 290 | # style_grid_size = 1 时保持原始 27x27 网格 291 | if style_grid_size == 1: 292 | # 直接使用原始的 cond,不需要任何插值 293 | pass 294 | else: 295 | cond = cond.view(b, m, m, h) 296 | cond = cond.permute(0, 3, 1, 2) # [B, C, H, W] 297 | cond = torch.nn.functional.interpolate( 298 | cond, 299 | size=(target_size, target_size), 300 | mode=interpolation_mode, 301 | align_corners=True if interpolation_mode in ["bicubic", "bilinear"] else None 302 | ) 303 | cond = cond.permute(0, 2, 3, 1) # [B, H, W, C] 304 | cond = cond.reshape(b, target_size * target_size, h) 305 | 306 | # 应用风格权重 307 | cond = cond * (reference_influence * reference_influence) 308 | 309 | # 合条件 310 | c = [] 311 | for t in conditioning: 312 | # 先应用提示词权重 313 | prompt_cond = t[0] * (prompt_influence * prompt_influence) 314 | 315 | # 合并条件,确保提示词在前,风格条件在后 316 | combined_cond = torch.cat((prompt_cond, cond), dim=1) 317 | 318 | # 保持原始的 cross attention 和其他参数 319 | n = [combined_cond, t[1].copy()] 320 | c.append(n) 321 | 322 | return (c, processed_image) 323 | 324 | # 节点注册 325 | NODE_CLASS_MAPPINGS = { 326 | "ReduxPromptStyler": ReduxPromptStyler 327 | } 328 | 329 | NODE_DISPLAY_NAME_MAPPINGS = { 330 | "ReduxPromptStyler": "Redux Style with Prompt Control" 331 | } -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | numpy 2 | torch -------------------------------------------------------------------------------- /服饰一致性.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CY-CHENYUE/ComfyUI-Redux-Prompt/50ebbfdce9cf42788fbcf661d61b5a163e462856/服饰一致性.png --------------------------------------------------------------------------------