Files
Superside-comfyui-superside…/modules/seedvr_2_upscale_image_node.py
T
Superside ComfyUI Nodes 6ebd0aa6cd Initial import: 28 fal.ai ComfyUI nodes with per-node API key input
Ported and curated from the internal fal-flux-nodes package: dropped
3 redundant nodes (Nano Banana v1, AnyVLM, SeedVR v1) that were fully
superseded by newer variants already in the set. Every node now takes
an explicit api_key STRING input instead of reading from a config file
or environment variable, so no key is ever baked into this repo.
2026-07-09 11:00:57 -04:00

111 lines
3.6 KiB
Python

import logging
from .base_node import (
APIClientMixin,
SupersideFalNode,
ImageProcessingMixin,
API_KEY_INPUT_SPEC,
)
logger = logging.getLogger(__name__)
class SeedVR2UpscaleImageNode(
SupersideFalNode, ImageProcessingMixin, APIClientMixin
):
"""
SeedVR v2 Upscale Image Node: Upscale images using SeedVR's seamless
image upscaler via fal.ai API.
"""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"image": ("IMAGE",),
"api_key": API_KEY_INPUT_SPEC,
},
"optional": {
"upscale_mode": (["target", "factor"], {"default": "factor"}),
"upscale_factor": (
"FLOAT",
{
"default": 2.0,
"min": 1.0,
"max": 10.0,
"step": 0.1,
"display": "slider",
},
),
"target_resolution": (
["720p", "1080p", "1440p", "2160p"],
{"default": "1080p"},
),
"seed": ("INT", {"min": 0, "max": 0xFFFFFFFFFFFFFFFF}),
"noise_scale": (
"FLOAT",
{
"default": 0.1,
"min": 0.0,
"max": 1.0,
"step": 0.001,
"display": "slider",
},
),
},
}
RETURN_TYPES = ("IMAGE",)
FUNCTION = "upscale"
DISPLAY_NAME = "SeedVR2 Upscale Image"
DESCRIPTION = "Upscale images using SeedVR2 seamless image upscaling"
def prepare_arguments(self, client, image, **kwargs):
"""Prepare arguments for the API call."""
arguments = {
"image_url": self.upload_image(client, image),
}
if kwargs.get("upscale_mode") is not None:
arguments["upscale_mode"] = kwargs["upscale_mode"]
if kwargs.get("target_resolution") is not None:
arguments["target_resolution"] = kwargs["target_resolution"]
if kwargs.get("upscale_factor") is not None:
arguments["upscale_factor"] = kwargs["upscale_factor"]
if kwargs.get("noise_scale") is not None:
arguments["noise_scale"] = kwargs["noise_scale"]
if kwargs.get("seed") not in (None, 0):
arguments["seed"] = kwargs["seed"]
return arguments
def process_seedvr_result(self, result):
"""Process SeedVR's single-image response format."""
if "image" not in result or not result["image"]:
raise RuntimeError("No image was generated by the API.")
img_info = result["image"]
logger.debug(f"Processing SeedVR 2 image: {img_info}")
if not isinstance(img_info, dict) or "url" not in img_info:
raise RuntimeError("Invalid image format in response")
return self.process_images({"images": [img_info]})
def upscale(self, image, api_key, **kwargs):
"""Main upscaling function."""
try:
client = self.get_client(api_key)
arguments = self.prepare_arguments(client, image, **kwargs)
logger.info(f"Calling SeedVR 2 API with arguments: {arguments}")
result = self.call_api(client, "fal-ai/seedvr/upscale/image/seamless", arguments)
return self.process_seedvr_result(result)
except Exception as e:
logger.error(f"SeedVR 2 upscaling failed: {str(e)}")
raise