commit 5d9eb66796385f0b2db6794e53cb21cb1cbd9c14 Author: sugarkwork Date: Fri Feb 7 00:49:40 2025 +0900 first commit diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..2396152 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 sugarkwork + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..3875581 --- /dev/null +++ b/README.md @@ -0,0 +1,36 @@ +# comfyui_psd + +このコードは、ComfyUI に PSD ファイルを出力する機能を追加します。 + +まだテスト版であり、正常に動作しない可能性や、環境を壊す可能性があります。 + +# install + + cd ComfyUI\custom_nodes + git clone https://github.com/sugarkwork/comfyui_psd.git + cd comfyui_psd + .\install.bat + +install.bat を叩く必要があります。 + +上手く動かないかもしれません……。 + +# how to use + +使い方は、 + +1. まず PSDLayer ノードを作成し、image に画像を接続します。 +2. レイヤー名前や合成モードを指定します。 +3. 新しい PSDLayer ノードを作成します。 +4. 先に作成した PSDLayer ノードの出力の PSD を、新しい PSDLayer の入力に入れて、同じように画像や名前やモードを指定します。 +5. レイヤーを追加した順に、下から積み重なります。つまり最初の PSDLayer が一番背景になります。 +6. 最後に Save PSD ノードに PSD を接続すると、最終的な PSD ファイルが保存されます。 + + +# sample node + +![image](https://github.com/user-attachments/assets/8c99ee84-6ac2-4451-8e7e-73a0f23ab9a3) + +# sample result + +![image](https://github.com/user-attachments/assets/3a0aa7bf-4c9c-4923-89f9-3bf6c7363cea) diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..71e1b56 --- /dev/null +++ b/__init__.py @@ -0,0 +1,3 @@ +from .nodes import * + +__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS'] diff --git a/nodes.py b/nodes.py new file mode 100644 index 0000000..2c1a0a3 --- /dev/null +++ b/nodes.py @@ -0,0 +1,134 @@ +from typing import Tuple + +class ResolutionSize: + def __init__(self, width, height): + self.width = width + self.height = height + + def __str__(self): + return f"{self.width}x{self.height}" + + def __repr__(self): + return f"{self.width}x{self.height}" + + def __eq__(self, other): + return self.width == other.width and self.height == other.height + + +class SizeToWidthHeight: + def __init__(self): + pass + + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "size": ("SIZE", ), + } + } + + RETURN_NAMES = ("Width", "Height", "LargeSide", "SmallSide") + RETURN_TYPES = ("INT", "INT", "INT", "INT") + + FUNCTION = "size_to_width_height" + OUTPUT_NODE = True + + def size_to_width_height(self, size) -> Tuple[int, int, int, int]: + print(size, type(size)) + return (size.width, size.height, max(size.width, size.height), min(size.width, size.height), ) + + +class AspectRatioToSize: + def __init__(self): + pass + + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "aspect_ratio": ("STRING", {"default": "16:9"}), + "resolution": ("INT", {"default": 1920, "min": 128, "max": 1024 * 8, "step": 64}), + } + } + + RETURN_NAMES = ("Size",) + RETURN_TYPES = ("SIZE",) + + FUNCTION = "aspect_ratio_to_size" + OUTPUT_NODE = True + + CATEGORY = "image" + + def aspect_ratio_to_size(self, aspect_ratio, resolution) -> ResolutionSize: + aspect_ratio = aspect_ratio.split(":") + width_ratio = max(0, float(aspect_ratio[0])) + height_ratio = max(0, float(aspect_ratio[1])) + + if width_ratio == 0 or height_ratio == 0: + return (ResolutionSize(0, 0),) + + width = 0 + height = 0 + if width_ratio > height_ratio: + width = resolution + height = int(resolution / width_ratio * height_ratio) + else: + height = resolution + width = int(resolution / height_ratio * width_ratio) + + if width < 0: + width = 0 + if height < 0: + height = 0 + + resolution_size = ResolutionSize(width=width, height=height) + + return (resolution_size,) + + +NODE_CLASS_MAPPINGS = { + "AspectRatioToSize": AspectRatioToSize, + "SizeToWidthHeight": SizeToWidthHeight +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "AspectRatioToSize": "AspectRatioToSize", + "SizeToWidthHeight": "SizeToWidthHeight" +} + + +def simple_test(): + node = AspectRatioToSize() + + ratio = "16:9" + result = node.aspect_ratio_to_size(ratio, 1920) + print(ratio, result) + + ratio = "9:16" + result = node.aspect_ratio_to_size(ratio, 1920) + print(ratio, result) + + ratio = "4:3" + result = node.aspect_ratio_to_size(ratio, 640) + print(ratio, result) + + ratio = "3:4" + result = node.aspect_ratio_to_size(ratio, 640) + print(ratio, result) + + ratio = "1:1" + result = node.aspect_ratio_to_size(ratio, 640) + print(ratio, result) + + ratio = "1:0.5625" + result = node.aspect_ratio_to_size(ratio, 1920) + print(ratio, result) + + node = SizeToWidthHeight() + size = ResolutionSize(1920, 1080) + result = node.size_to_width_height(size) + print(size, result) + + +#if __name__ == "__main__": +# simple_test()