214 lines
8.1 KiB
Markdown
214 lines
8.1 KiB
Markdown
|
|
# Documentation
|
|
- Class name: `SaltInput`
|
|
- Category: `SALT/IO`
|
|
- Output node: `True`
|
|
|
|
SaltInput节点旨在为Salt AI平台的工作流创建和配置输入。它允许用户定义输入的各个方面,如名称、描述、类型和默认值,以及其他属性,如允许的值、是否需要用户覆盖,以及路径是否应被视为相对路径。该节点在为不同类型的数据定制和简化输入过程中发挥着关键作用,确保工作流设计的灵活性和适应性。
|
|
|
|
# Input types
|
|
## Required
|
|
- **`input_name`**
|
|
- 指定输入的名称,作为工作流中输入字段的唯一标识符和标签。
|
|
- Comfy dtype: `STRING`
|
|
- Python dtype: `str`
|
|
- **`input_desc`**
|
|
- 为输入提供描述,为用户提供关于如何提供输入值的上下文或说明。
|
|
- Comfy dtype: `STRING`
|
|
- Python dtype: `str`
|
|
- **`input_type`**
|
|
- 定义输入的类型,如STRING、FLOAT、INT等,决定了用户需要提供的数据的预期格式和性质。
|
|
- Comfy dtype: `COMBO[STRING]`
|
|
- Python dtype: `list[str]`
|
|
- **`input_value`**
|
|
- 输入的默认值,可以预先填写但用户可以更改。支持多行字符串,设计用于动态输入场景。
|
|
- Comfy dtype: `STRING`
|
|
- Python dtype: `str`
|
|
## Optional
|
|
- **`input_image`**
|
|
- 可选参数,用于提供图像作为输入,增强节点处理视觉数据类型的能力。
|
|
- Comfy dtype: `IMAGE`
|
|
- Python dtype: `Image`
|
|
- **`input_mask`**
|
|
- 可选参数,用于提供蒙版作为输入,在需要识别或处理图像特定区域的场景中很有用。
|
|
- Comfy dtype: `MASK`
|
|
- Python dtype: `Mask`
|
|
- **`input_allowed_values`**
|
|
- 指定输入允许值的字符串,指导用户提供有效数据并确保输入完整性。
|
|
- Comfy dtype: `STRING`
|
|
- Python dtype: `str`
|
|
- **`user_override_required`**
|
|
- 确定用户是否必须为默认输入值提供覆盖,确保关键输入的用户交互和验证。
|
|
- Comfy dtype: `BOOLEAN`
|
|
- Python dtype: `bool`
|
|
- **`relative_path`**
|
|
- 指示提供的输入路径是否应被视为相对路径,影响输入数据的访问和管理方式。
|
|
- Comfy dtype: `BOOLEAN`
|
|
- Python dtype: `bool`
|
|
|
|
# Output types
|
|
- **`value`**
|
|
- 输出配置的输入值。
|
|
- Comfy dtype: `*`
|
|
- Python dtype: `unknown`
|
|
- **`ui`**
|
|
- 生成输入配置的用户界面表示,包括元数据和输出结果,便于交互和视觉反馈。
|
|
- Comfy dtype: `*`
|
|
- Python dtype: `unknown`
|
|
|
|
|
|
## Usage tips
|
|
- Infra type: `CPU`
|
|
- Common nodes: unknown
|
|
|
|
|
|
## Source code
|
|
```python
|
|
class SaltInput:
|
|
@classmethod
|
|
def INPUT_TYPES(cls):
|
|
return {
|
|
"required": {
|
|
"input_name": ("STRING", {}),
|
|
"input_desc": ("STRING", {}),
|
|
"input_type": (["STRING", "FLOAT", "INT", "BOOLEAN", "IMAGE", "MASK", "SEED", "FILE"],),
|
|
"input_value": ("STRING", {"multiline": True, "dynamicPrompts": False})
|
|
},
|
|
"optional": {
|
|
"input_image": ("IMAGE",),
|
|
"input_mask": ("MASK",),
|
|
"input_allowed_values": ("STRING", {"default": ""}),
|
|
"user_override_required": ("BOOLEAN", {"default": False}),
|
|
"relative_path": ("BOOLEAN", {"default": False})
|
|
},
|
|
"hidden": {"unique_id": "UNIQUE_ID"},
|
|
}
|
|
|
|
OUTPUT_NODE = True
|
|
RETURN_TYPES = (WILDCARD,)
|
|
RETURN_NAMES = ("value",)
|
|
|
|
FUNCTION = "input"
|
|
CATEGORY = "SALT/IO"
|
|
|
|
def input(
|
|
self,
|
|
input_name,
|
|
input_desc,
|
|
input_value,
|
|
input_type,
|
|
input_image=None,
|
|
input_mask=None,
|
|
input_allowed_values="",
|
|
user_override_required=False,
|
|
relative_path=False,
|
|
unique_id=0,
|
|
):
|
|
src_image = None
|
|
src_file = None
|
|
is_asset = False
|
|
|
|
# Is an asset type
|
|
if input_type in ["IMAGE", "MASK", "FILE"]:
|
|
is_asset = True
|
|
|
|
# UI Output
|
|
ui = {
|
|
"ui": {
|
|
"salt_input": [{
|
|
"id": unique_id,
|
|
"name": input_name or "input_" + str(unique_id),
|
|
"description": input_desc or "",
|
|
"asset": is_asset or False,
|
|
"type": input_type or "string",
|
|
"value": input_value or "",
|
|
}]
|
|
}
|
|
}
|
|
|
|
out = ""
|
|
if is_asset:
|
|
# Input value must be evaluated first to override input images/masks
|
|
if input_value.strip():
|
|
input_value = input_value.strip()
|
|
# Load image from path from input_value
|
|
if input_value.endswith(('.png', '.jpeg', '.jpg', '.gif', '.webp', '.tiff')):
|
|
try:
|
|
src_image = Image.open(input_value).convert("RGBA")
|
|
except Exception as e:
|
|
print(f"Error loading image from specified path {input_value}: {e}")
|
|
# Passthrough input_value (which should be a path from Salt Backend)
|
|
elif input_type == "FILE":
|
|
|
|
src_file = input_value # if os.path.exists(input_value) else "None"
|
|
if relative_path:
|
|
src_file = get_relative_path(src_file)
|
|
|
|
# Log value to console
|
|
log_values(unique_id, input_name, input_type, src_file)
|
|
|
|
return {"ui": ui, "result": (src_file,)}
|
|
else:
|
|
# Zoinks; how'd we get here?
|
|
raise AttributeError("Invalid node configuration! Do you mean to use `IMAGE`, `MASK`, or `FILE` input_types?")
|
|
elif isinstance(input_image, torch.Tensor):
|
|
# Input `IMAGE` is provided, so we act like a passthrough
|
|
return (input_image, ui)
|
|
elif isinstance(input_mask, torch.Tensor):
|
|
# Input `MASK` is provided, so we act like a passthrough
|
|
return (input_mask, ui)
|
|
|
|
if src_image:
|
|
if input_type == "MASK":
|
|
# If it's a mask and the image has an alpha channel, extract it
|
|
if src_image.mode == "RGBA":
|
|
alpha_channel = src_image.split()[-1]
|
|
src_image = pil2mask(alpha_channel.convert("L"))
|
|
# If no alpha channel, convert the whole image to grayscale as a mask (could be bitwise representation)
|
|
else:
|
|
src_image = pil2mask(src_image.convert("L"))
|
|
elif input_type == "IMAGE":
|
|
# Ensure image is in RGB for `IMAGE`` data type
|
|
src_image = pil2tensor(src_image.convert("RGB"))
|
|
|
|
else:
|
|
# Gracefully allow execution to continue, provided a black image (to hopefully signal issue?)
|
|
print("[WARNING] Unable to determine IMAGE or MASK to load!")
|
|
print("[WARNING] Returning image blank")
|
|
src_blank = Image.new("RGB", (512, 512), (0, 0, 0))
|
|
if input_type == "IMAGE":
|
|
src_image = pil2tensor(src_blank)
|
|
else:
|
|
src_image = pil2mask(src_blank)
|
|
|
|
# Log value to console
|
|
log_values(unique_id, input_name, input_type, src_image)
|
|
|
|
return (src_image, ui)
|
|
|
|
# We're still here? We must be dealing with a primitive value
|
|
if input_allowed_values != "" and input_value.strip() not in [o.strip() for o in input_allowed_values.split(',')]:
|
|
raise ValueError('The provided input is not a supported value')
|
|
|
|
|
|
match input_type:
|
|
case "STRING":
|
|
out = str(input_value)
|
|
case "INT":
|
|
out = int(input_value)
|
|
case "SEED":
|
|
out = int(input_value)
|
|
case "FLOAT":
|
|
out = float(input_value)
|
|
case "BOOLEAN":
|
|
out = bool_str(input_value)
|
|
case _:
|
|
out = input_value
|
|
|
|
# Log value to console
|
|
log_values(unique_id, input_name, input_type, out)
|
|
|
|
return (out, ui)
|
|
|
|
```
|