first commit
This commit is contained in:
@@ -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.
|
||||
@@ -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
|
||||
|
||||

|
||||
|
||||
# sample result
|
||||
|
||||

|
||||
@@ -0,0 +1,3 @@
|
||||
from .nodes import *
|
||||
|
||||
__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS']
|
||||
@@ -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()
|
||||
Reference in New Issue
Block a user