mirror of
https://github.com/Comfy-Org/ComfyUI.git
synced 2026-08-05 18:05:08 +08:00
[Partner Nodes] feat(Recraft): add V4.1 model (#15105)
* [Partner Nodes] feat(Recraft): add V4.1 models and V4 image edit nodes Signed-off-by: bigcat88 <bigcat88@icloud.com> * [Partner Nodes] chore(Recraft): change old nodes names to contain "V3" Signed-off-by: bigcat88 <bigcat88@icloud.com> * [Partner Nodes] fix(Recraft): remove v4 model from the image edit nodes; fix the default "strength" value Signed-off-by: bigcat88 <bigcat88@icloud.com> * [Partner Nodes] chore(Recraft): remove new image edit nodes Signed-off-by: bigcat88 <bigcat88@icloud.com> --------- Signed-off-by: bigcat88 <bigcat88@icloud.com>
This commit is contained in:
@@ -244,10 +244,10 @@ RECRAFT_V4_PRO_SIZES = [
|
|||||||
"2304x1792",
|
"2304x1792",
|
||||||
"1792x2304",
|
"1792x2304",
|
||||||
"1664x2688",
|
"1664x2688",
|
||||||
"1434x1024",
|
|
||||||
"1024x1434",
|
|
||||||
"2560x1792",
|
"2560x1792",
|
||||||
"1792x2560",
|
"1792x2560",
|
||||||
|
"2688x1536",
|
||||||
|
"1536x2688",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -399,7 +399,7 @@ class RecraftTextToImageNode(IO.ComfyNode):
|
|||||||
def define_schema(cls):
|
def define_schema(cls):
|
||||||
return IO.Schema(
|
return IO.Schema(
|
||||||
node_id="RecraftTextToImageNode",
|
node_id="RecraftTextToImageNode",
|
||||||
display_name="Recraft Text to Image",
|
display_name="Recraft V3 Text to Image",
|
||||||
category="partner/image/Recraft",
|
category="partner/image/Recraft",
|
||||||
description="Generates images synchronously based on prompt and resolution.",
|
description="Generates images synchronously based on prompt and resolution.",
|
||||||
inputs=[
|
inputs=[
|
||||||
@@ -511,7 +511,7 @@ class RecraftImageToImageNode(IO.ComfyNode):
|
|||||||
def define_schema(cls):
|
def define_schema(cls):
|
||||||
return IO.Schema(
|
return IO.Schema(
|
||||||
node_id="RecraftImageToImageNode",
|
node_id="RecraftImageToImageNode",
|
||||||
display_name="Recraft Image to Image",
|
display_name="Recraft V3 Image to Image",
|
||||||
category="partner/image/Recraft",
|
category="partner/image/Recraft",
|
||||||
description="Modify image based on prompt and strength.",
|
description="Modify image based on prompt and strength.",
|
||||||
inputs=[
|
inputs=[
|
||||||
@@ -731,7 +731,7 @@ class RecraftTextToVectorNode(IO.ComfyNode):
|
|||||||
def define_schema(cls):
|
def define_schema(cls):
|
||||||
return IO.Schema(
|
return IO.Schema(
|
||||||
node_id="RecraftTextToVectorNode",
|
node_id="RecraftTextToVectorNode",
|
||||||
display_name="Recraft Text to Vector",
|
display_name="Recraft V3 Text to Vector",
|
||||||
category="partner/image/Recraft",
|
category="partner/image/Recraft",
|
||||||
description="Generates SVG synchronously based on prompt and resolution.",
|
description="Generates SVG synchronously based on prompt and resolution.",
|
||||||
inputs=[
|
inputs=[
|
||||||
@@ -1087,7 +1087,7 @@ class RecraftV4TextToImageNode(IO.ComfyNode):
|
|||||||
node_id="RecraftV4TextToImageNode",
|
node_id="RecraftV4TextToImageNode",
|
||||||
display_name="Recraft V4 Text to Image",
|
display_name="Recraft V4 Text to Image",
|
||||||
category="partner/image/Recraft",
|
category="partner/image/Recraft",
|
||||||
description="Generates images using Recraft V4 or V4 Pro models.",
|
description="Generates images using Recraft V4 and V4.1 models.",
|
||||||
inputs=[
|
inputs=[
|
||||||
IO.String.Input(
|
IO.String.Input(
|
||||||
"prompt",
|
"prompt",
|
||||||
@@ -1097,11 +1097,56 @@ class RecraftV4TextToImageNode(IO.ComfyNode):
|
|||||||
IO.String.Input(
|
IO.String.Input(
|
||||||
"negative_prompt",
|
"negative_prompt",
|
||||||
multiline=True,
|
multiline=True,
|
||||||
tooltip="An optional text description of undesired elements on an image.",
|
tooltip="This input is ignored: negative prompt is not supported by "
|
||||||
|
"Recraft V4 and V4.1 models.",
|
||||||
),
|
),
|
||||||
IO.DynamicCombo.Input(
|
IO.DynamicCombo.Input(
|
||||||
"model",
|
"model",
|
||||||
options=[
|
options=[
|
||||||
|
IO.DynamicCombo.Option(
|
||||||
|
"recraftv4_1",
|
||||||
|
[
|
||||||
|
IO.Combo.Input(
|
||||||
|
"size",
|
||||||
|
options=RECRAFT_V4_SIZES,
|
||||||
|
default="1024x1024",
|
||||||
|
tooltip="The size of the generated image.",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
IO.DynamicCombo.Option(
|
||||||
|
"recraftv4_1_utility",
|
||||||
|
[
|
||||||
|
IO.Combo.Input(
|
||||||
|
"size",
|
||||||
|
options=RECRAFT_V4_SIZES,
|
||||||
|
default="1024x1024",
|
||||||
|
tooltip="The size of the generated image.",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
IO.DynamicCombo.Option(
|
||||||
|
"recraftv4_1_pro",
|
||||||
|
[
|
||||||
|
IO.Combo.Input(
|
||||||
|
"size",
|
||||||
|
options=RECRAFT_V4_PRO_SIZES,
|
||||||
|
default="2048x2048",
|
||||||
|
tooltip="The size of the generated image.",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
IO.DynamicCombo.Option(
|
||||||
|
"recraftv4_1_utility_pro",
|
||||||
|
[
|
||||||
|
IO.Combo.Input(
|
||||||
|
"size",
|
||||||
|
options=RECRAFT_V4_PRO_SIZES,
|
||||||
|
default="2048x2048",
|
||||||
|
tooltip="The size of the generated image.",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
IO.DynamicCombo.Option(
|
IO.DynamicCombo.Option(
|
||||||
"recraftv4",
|
"recraftv4",
|
||||||
[
|
[
|
||||||
@@ -1162,7 +1207,14 @@ class RecraftV4TextToImageNode(IO.ComfyNode):
|
|||||||
depends_on=IO.PriceBadgeDepends(widgets=["model", "n"]),
|
depends_on=IO.PriceBadgeDepends(widgets=["model", "n"]),
|
||||||
expr="""
|
expr="""
|
||||||
(
|
(
|
||||||
$prices := {"recraftv4": 0.04, "recraftv4_pro": 0.25};
|
$prices := {
|
||||||
|
"recraftv4_1": 0.035,
|
||||||
|
"recraftv4_1_utility": 0.035,
|
||||||
|
"recraftv4_1_pro": 0.21,
|
||||||
|
"recraftv4_1_utility_pro": 0.21,
|
||||||
|
"recraftv4": 0.04,
|
||||||
|
"recraftv4_pro": 0.25
|
||||||
|
};
|
||||||
{"type":"usd","usd": $lookup($prices, widgets.model) * widgets.n}
|
{"type":"usd","usd": $lookup($prices, widgets.model) * widgets.n}
|
||||||
)
|
)
|
||||||
""",
|
""",
|
||||||
@@ -1179,14 +1231,13 @@ class RecraftV4TextToImageNode(IO.ComfyNode):
|
|||||||
seed: int,
|
seed: int,
|
||||||
recraft_controls: RecraftControls | None = None,
|
recraft_controls: RecraftControls | None = None,
|
||||||
) -> IO.NodeOutput:
|
) -> IO.NodeOutput:
|
||||||
validate_string(prompt, strip_whitespace=False, min_length=1, max_length=10000)
|
validate_string(prompt, strip_whitespace=True, min_length=1, max_length=10000)
|
||||||
response = await sync_op(
|
response = await sync_op(
|
||||||
cls,
|
cls,
|
||||||
ApiEndpoint(path="/proxy/recraft/image_generation", method="POST"),
|
ApiEndpoint(path="/proxy/recraft/image_generation", method="POST"),
|
||||||
response_model=RecraftImageGenerationResponse,
|
response_model=RecraftImageGenerationResponse,
|
||||||
data=RecraftImageGenerationRequest(
|
data=RecraftImageGenerationRequest(
|
||||||
prompt=prompt,
|
prompt=prompt,
|
||||||
negative_prompt=negative_prompt if negative_prompt else None,
|
|
||||||
model=model["model"],
|
model=model["model"],
|
||||||
size=model["size"],
|
size=model["size"],
|
||||||
n=n,
|
n=n,
|
||||||
@@ -1211,7 +1262,7 @@ class RecraftV4TextToVectorNode(IO.ComfyNode):
|
|||||||
node_id="RecraftV4TextToVectorNode",
|
node_id="RecraftV4TextToVectorNode",
|
||||||
display_name="Recraft V4 Text to Vector",
|
display_name="Recraft V4 Text to Vector",
|
||||||
category="partner/image/Recraft",
|
category="partner/image/Recraft",
|
||||||
description="Generates SVG using Recraft V4 or V4 Pro models.",
|
description="Generates SVG using Recraft V4 and V4.1 models.",
|
||||||
inputs=[
|
inputs=[
|
||||||
IO.String.Input(
|
IO.String.Input(
|
||||||
"prompt",
|
"prompt",
|
||||||
@@ -1221,11 +1272,56 @@ class RecraftV4TextToVectorNode(IO.ComfyNode):
|
|||||||
IO.String.Input(
|
IO.String.Input(
|
||||||
"negative_prompt",
|
"negative_prompt",
|
||||||
multiline=True,
|
multiline=True,
|
||||||
tooltip="An optional text description of undesired elements on an image.",
|
tooltip="This input is ignored: negative prompt is not supported by "
|
||||||
|
"Recraft V4 and V4.1 models.",
|
||||||
),
|
),
|
||||||
IO.DynamicCombo.Input(
|
IO.DynamicCombo.Input(
|
||||||
"model",
|
"model",
|
||||||
options=[
|
options=[
|
||||||
|
IO.DynamicCombo.Option(
|
||||||
|
"recraftv4_1_vector",
|
||||||
|
[
|
||||||
|
IO.Combo.Input(
|
||||||
|
"size",
|
||||||
|
options=RECRAFT_V4_SIZES,
|
||||||
|
default="1024x1024",
|
||||||
|
tooltip="The size of the generated image.",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
IO.DynamicCombo.Option(
|
||||||
|
"recraftv4_1_utility_vector",
|
||||||
|
[
|
||||||
|
IO.Combo.Input(
|
||||||
|
"size",
|
||||||
|
options=RECRAFT_V4_SIZES,
|
||||||
|
default="1024x1024",
|
||||||
|
tooltip="The size of the generated image.",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
IO.DynamicCombo.Option(
|
||||||
|
"recraftv4_1_pro_vector",
|
||||||
|
[
|
||||||
|
IO.Combo.Input(
|
||||||
|
"size",
|
||||||
|
options=RECRAFT_V4_PRO_SIZES,
|
||||||
|
default="2048x2048",
|
||||||
|
tooltip="The size of the generated image.",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
IO.DynamicCombo.Option(
|
||||||
|
"recraftv4_1_utility_pro_vector",
|
||||||
|
[
|
||||||
|
IO.Combo.Input(
|
||||||
|
"size",
|
||||||
|
options=RECRAFT_V4_PRO_SIZES,
|
||||||
|
default="2048x2048",
|
||||||
|
tooltip="The size of the generated image.",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
IO.DynamicCombo.Option(
|
IO.DynamicCombo.Option(
|
||||||
"recraftv4",
|
"recraftv4",
|
||||||
[
|
[
|
||||||
@@ -1286,7 +1382,14 @@ class RecraftV4TextToVectorNode(IO.ComfyNode):
|
|||||||
depends_on=IO.PriceBadgeDepends(widgets=["model", "n"]),
|
depends_on=IO.PriceBadgeDepends(widgets=["model", "n"]),
|
||||||
expr="""
|
expr="""
|
||||||
(
|
(
|
||||||
$prices := {"recraftv4": 0.08, "recraftv4_pro": 0.30};
|
$prices := {
|
||||||
|
"recraftv4_1_vector": 0.08,
|
||||||
|
"recraftv4_1_utility_vector": 0.08,
|
||||||
|
"recraftv4_1_pro_vector": 0.30,
|
||||||
|
"recraftv4_1_utility_pro_vector": 0.30,
|
||||||
|
"recraftv4": 0.08,
|
||||||
|
"recraftv4_pro": 0.30
|
||||||
|
};
|
||||||
{"type":"usd","usd": $lookup($prices, widgets.model) * widgets.n}
|
{"type":"usd","usd": $lookup($prices, widgets.model) * widgets.n}
|
||||||
)
|
)
|
||||||
""",
|
""",
|
||||||
@@ -1303,18 +1406,17 @@ class RecraftV4TextToVectorNode(IO.ComfyNode):
|
|||||||
seed: int,
|
seed: int,
|
||||||
recraft_controls: RecraftControls | None = None,
|
recraft_controls: RecraftControls | None = None,
|
||||||
) -> IO.NodeOutput:
|
) -> IO.NodeOutput:
|
||||||
validate_string(prompt, strip_whitespace=False, min_length=1, max_length=10000)
|
validate_string(prompt, strip_whitespace=True, min_length=1, max_length=10000)
|
||||||
response = await sync_op(
|
response = await sync_op(
|
||||||
cls,
|
cls,
|
||||||
ApiEndpoint(path="/proxy/recraft/image_generation", method="POST"),
|
ApiEndpoint(path="/proxy/recraft/image_generation", method="POST"),
|
||||||
response_model=RecraftImageGenerationResponse,
|
response_model=RecraftImageGenerationResponse,
|
||||||
data=RecraftImageGenerationRequest(
|
data=RecraftImageGenerationRequest(
|
||||||
prompt=prompt,
|
prompt=prompt,
|
||||||
negative_prompt=negative_prompt if negative_prompt else None,
|
|
||||||
model=model["model"],
|
model=model["model"],
|
||||||
size=model["size"],
|
size=model["size"],
|
||||||
n=n,
|
n=n,
|
||||||
style="vector_illustration",
|
style=None if model["model"].endswith("_vector") else "vector_illustration",
|
||||||
substyle=None,
|
substyle=None,
|
||||||
controls=recraft_controls.create_api_model() if recraft_controls else None,
|
controls=recraft_controls.create_api_model() if recraft_controls else None,
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user