跳转到主要内容

Documentation Index

Fetch the complete documentation index at: https://dripart-mintlify-e28287af.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

ComfyUI 原生 Luma Image to Image 节点 Luma Image to Image 节点允许你使用 Luma AI 的技术根据文本提示词修改现有图像,同时保留原始图像的某些特征和结构。

节点功能

此节点连接到Luma AI的文本到图像API,让用户能够通过详细的文本提示词生成图像。Luma AI以其出色的真实感和细节表现而闻名,特别擅长生成照片级别的逼真内容和艺术风格图像。

参数说明

基本参数

参数类型默认值说明
prompt字符串""描述要生成内容的文本提示词
model选择项-选择使用的生成模型
aspect_ratio选择项16:9设置输出图像的宽高比
seed整数0种子值,用于确定节点是否应重新运行,但实际结果与种子无关
style_image_weight浮点数1.0样式图像的权重,范围0.02-1.0,仅在提供style_image时生效

可选参数

在没有下列参数输入的情况下,对应的节点为文生图模式
参数类型说明
image_luma_refLUMA_REFLuma参考节点连接,通过输入图像影响生成结果,最多可考虑4张图像
style_image图像样式参考图像,仅使用1张图像,影响图像生成的风格,通过 style_image_weight 调整权重
character_image图像将角色特征加入到生成结果中,可以是多张图像的批次,最多可提供4张图像

输出

输出类型说明
IMAGE图像生成的图像结果

使用示例

工作原理

Luma Image to Image 节点分析输入图像并结合文本提示词来引导修改过程。它使用 Luma AI 的生成模型,根据提示词对图像进行创新性的变化。 节点流程:
  1. 首先将输入图像上传到 ComfyAPI
  2. 然后将图像 URL 与提示词发送到 Luma API
  3. 等待 Luma AI 完成处理
  4. 下载并返回生成的图像
image_weight 参数控制原始图像的影响程度 - 接近 0 的值会更多地保留原始图像特征,而接近 1 的值则允许更大幅度的修改。

源码参考

[节点源码 (更新于 2025-05-05)]

class LumaImageModifyNode(ComfyNodeABC):
    """
    Modifies images synchronously based on prompt and aspect ratio.
    """

    RETURN_TYPES = (IO.IMAGE,)
    DESCRIPTION = cleandoc(__doc__ or "")  # Handle potential None value
    FUNCTION = "api_call"
    API_NODE = True
    CATEGORY = "api node/image/Luma"

    @classmethod
    def INPUT_TYPES(s):
        return {
            "required": {
                "image": (IO.IMAGE,),
                "prompt": (
                    IO.STRING,
                    {
                        "multiline": True,
                        "default": "",
                        "tooltip": "Prompt for the image generation",
                    },
                ),
                "image_weight": (
                    IO.FLOAT,
                    {
                        "default": 1.0,
                        "min": 0.02,
                        "max": 1.0,
                        "step": 0.01,
                        "tooltip": "Weight of the image; the closer to 0.0, the less the image will be modified.",
                    },
                ),
                "model": ([model.value for model in LumaImageModel],),
                "seed": (
                    IO.INT,
                    {
                        "default": 0,
                        "min": 0,
                        "max": 0xFFFFFFFFFFFFFFFF,
                        "control_after_generate": True,
                        "tooltip": "Seed to determine if node should re-run; actual results are nondeterministic regardless of seed.",
                    },
                ),
            },
            "optional": {},
            "hidden": {
                "auth_token": "AUTH_TOKEN_COMFY_ORG",
            },
        }

    def api_call(
        self,
        prompt: str,
        model: str,
        image: torch.Tensor,
        image_weight: float,
        seed,
        auth_token=None,
        **kwargs,
    ):
        # first, upload image
        download_urls = upload_images_to_comfyapi(
            image, max_images=1, auth_token=auth_token
        )
        image_url = download_urls[0]
        # next, make Luma call with download url provided
        operation = SynchronousOperation(
            endpoint=ApiEndpoint(
                path="/proxy/luma/generations/image",
                method=HttpMethod.POST,
                request_model=LumaImageGenerationRequest,
                response_model=LumaGeneration,
            ),
            request=LumaImageGenerationRequest(
                prompt=prompt,
                model=model,
                modify_image_ref=LumaModifyImageRef(
                    url=image_url, weight=round(image_weight, 2)
                ),
            ),
            auth_token=auth_token,
        )
        response_api: LumaGeneration = operation.execute()

        operation = PollingOperation(
            poll_endpoint=ApiEndpoint(
                path=f"/proxy/luma/generations/{response_api.id}",
                method=HttpMethod.GET,
                request_model=EmptyRequest,
                response_model=LumaGeneration,
            ),
            completed_statuses=[LumaState.completed],
            failed_statuses=[LumaState.failed],
            status_extractor=lambda x: x.state,
            auth_token=auth_token,
        )
        response_poll = operation.execute()

        img_response = requests.get(response_poll.assets.image)
        img = process_image_response(img_response)
        return (img,)