Skip to main content
Esta página te guiará paso a paso por el proceso de crear un nodo personalizado. Nuestro ejemplo tomará un lote de imágenes y devolverá una de las imágenes. Inicialmente, el nodo devolverá la imagen que, en promedio, sea la más clara de color; luego lo extenderemos para que tenga una variedad de criterios de selección y, finalmente, agregaremos algo de código del lado del cliente. Esta página asume muy poco conocimiento de Python o Javascript. Después de este recorrido, profundiza en los detalles del código del backend y el código del frontend.

Escribir un nodo básico

Requisitos previos

  • Una instalación de ComfyUI en funcionamiento. Para desarrollo, recomendamos instalar ComfyUI manualmente.
  • Una instalación de comfy-cli en funcionamiento.

Configurar el entorno

Después de responder algunas preguntas, tendrás un nuevo directorio configurado.

Definir el nodo

Agrega el siguiente código al final de src/nodes.py:
src/nodes.py
La estructura básica de un nodo personalizado se describe en detalle aquí.
Un nodo personalizado se define con una clase de Python, que debe incluir estas cuatro cosas: CATEGORY, que especifica en qué parte del menú de agregar nuevo nodo se ubicará el nodo personalizado, INPUT_TYPES, que es un método de clase que define qué entradas recibirá el nodo (consulta más adelante los detalles del diccionario que devuelve), RETURN_TYPES, que define qué salidas producirá el nodo, y FUNCTION, el nombre de la función que se llamará cuando se ejecute el nodo.
Observa que el tipo de dato de entrada y salida es IMAGE (singular) aunque esperamos recibir un lote de imágenes y devolver solo una. En Comfy, IMAGE significa lote de imágenes, y una sola imagen se trata como un lote de tamaño 1.

La función principal

La función principal, choose_image, recibe argumentos con nombre tal como se definen en INPUT_TYPES y devuelve una tuple tal como se define en RETURN_TYPES. Como trabajamos con imágenes, que internamente se almacenan como torch.Tensor,
Luego agrega la función a tu clase. El tipo de dato de la imagen es torch.Tensor con forma [B,H,W,C], donde B es el tamaño del lote y C es el número de canales: 3, para RGB. Si iteramos sobre ese tensor, obtendremos una serie de B tensores con forma [H,W,C]. El método .flatten() lo convierte en un tensor unidimensional de longitud H*W*C, torch.mean() toma la media y .item() convierte un tensor de un solo valor en un float de Python.
Notas sobre esas dos últimas líneas:
  • images[brightest] devolverá un tensor con forma [H,W,C]. unsqueeze se usa para insertar una dimensión (de longitud 1), en este caso, en la dimensión cero, y obtener [B,H,W,C] con B=1: una sola imagen.
  • en return (result,), la coma final es esencial para asegurar que devuelves una tupla.

Registrar el nodo

Para que Comfy reconozca el nuevo nodo, debe estar disponible a nivel del paquete. Modifica la variable NODE_CLASS_MAPPINGS al final de src/nodes.py. Debes reiniciar ComfyUI para ver los cambios.
src/nodes.py
Para una explicación detallada de cómo ComfyUI descubre y carga los nodos personalizados, consulta la documentación del ciclo de vida de los nodos.

Añadir algunas opciones

Ese nodo quizá sea un poco aburrido, así que podríamos añadir algunas opciones: un widget que te permita elegir la imagen más brillante, o la más roja, la más azul o la más verde. Edita tu INPUT_TYPES para que quede así:
Después, actualiza la función principal. Usaremos una definición bastante ingenua de ‘reddest’ (lo más rojo) como el valor medio de R de los píxeles dividido por la media de los tres colores. Así:

Ajustar la interfaz

Quizá queramos algo de retroalimentación visual, así que enviemos un pequeño mensaje de texto para que se muestre.

Enviar un mensaje desde el servidor

Esto requiere agregar dos líneas al código Python:
y, al final del método choose_image, agrega una línea para enviar un mensaje al front end (send_sync recibe un tipo de mensaje, que debe ser único, y un diccionario)

Escribir una extensión de cliente

Para agregar algo de JavaScript al cliente, crea un subdirectorio, web/js, en el directorio de tu nodo personalizado y modifica el final de __init__.py para informarle a Comfy sobre él exportando WEB_DIRECTORY:
La extensión de cliente se guarda como un archivo .js en el subdirectorio web/js, así que crea image_selector/web/js/imageSelector.js con el código a continuación. (Para más información, consulta client side coding).
Lo único que hicimos fue registrar una extensión y agregar un detector para el tipo de mensaje que enviamos en el método setup(). Esto lee el diccionario que enviamos (que se almacena en event.detail). Detén el servidor de Comfy, inícialo de nuevo, recarga la página web y ejecuta tu flujo de trabajo.

El ejemplo completo

El ejemplo completo está disponible aquí. Puedes descargar el archivo JSON del flujo de trabajo de ejemplo o verlo a continuación:
Flujo de trabajo del selector de imágenes