Expansão de Capacidades através de Nós Customizados
Os nós personalizados permitem estender funcionalidades do ComfyUI além dos blocos padrão, possibilitando a integração de lógica específica, novos modelos ou rqeuisitos de negócios.
Anatomia de um Nó
Cada nó é uma classe Python que herda da estrutura base do framework, seguindo um cnotrato de entrada-processamento-saída. A execução ocorre de forma assíncrona mediante dependências de dados definidas pelas conexões visuais.
Implementação de Nó de Redimensionamento Inteligente
# custom_nodes/ajuste_imagem.py
import torch
import numpy as np
from PIL import Image
class AjustadorImagem:
CATEGORIA = "Processamento de Imagem"
@classmethod
def DEFINICOES_ENTRADA(cls):
return {
"obrigatorios": {
"imagem": ("IMAGEM",),
"largura_alvo": ("INTEIRO", {"padrao": 512}),
"altura_alvo": ("INTEIRO", {"padrao": 512}),
"metodo": (["preencher", "esticar"], {"padrao": "preencher"})
}
}
TIPOS_RETORNO = ("IMAGEM", "MASCARA")
FUNCAO = "ajustar"
def ajustar(self, imagem, largura_alvo, altura_alvo, metodo):
lote, alt, larg, canais = imagem.shape
img_np = imagem[0].cpu().numpy()
img_pil = Image.fromarray((img_np * 255).astype(np.uint8))
if metodo == "esticar":
resultado = img_pil.resize((largura_alvo, altura_alvo), Image.LANCZOS)
mascara = Image.new("L", (largura_alvo, altura_alvo), 255)
else:
escala = min(largura_alvo / larg, altura_alvo / alt)
nova_larg = int(larg * escala)
nova_alt = int(alt * escala)
temp_img = img_pil.resize((nova_larg, nova_alt), Image.LANCZOS)
resultado = Image.new("RGB", (largura_alvo, altura_alvo), (0,0,0))
x_offset = (largura_alvo - nova_larg) // 2
y_offset = (altura_alvo - nova_alt) // 2
resultado.paste(temp_img, (x_offset, y_offset))
mascara = Image.new("L", (largura_alvo, altura_alvo), 0)
mascara.paste(255, (x_offset, y_offset, x_offset+nova_larg, y_offset+nova_alt))
img_tensor = torch.from_numpy(np.array(resultado).astype(np.float32) / 255.0).unsqueeze(0)
mascara_tensor = torch.from_numpy(np.array(mascara).astype(np.float32) / 255.0).unsqueeze(0).unsqueeze(-1)
return (img_tensor, mascara_tensor)
Orquestração de Fluxos de Trabalho Complexos
Sistemas de geração avançada requerem pipelines estruturados como grafos acíclicos direcionados (DAG), onde o ComfyUI gerencia:
- Análise de dependências
- Ordenação topológica
- Execução sob demanda
- Reutilização de cache
- Diagnóstico de erros
Exemplo de Pipeline Automatizado
# gerador_fluxos.py
import json
def criar_pipeline(modelo_base, passos=15):
componentes = []
conexoes = []
contador_id = 1
carregador = {
"id": contador_id,
"tipo": "CarregadorModelo",
"valores": [modelo_base]
}
id_carregador = contador_id
contador_id += 1
codificador_positivo = {
"id": contador_id,
"tipo": "CodificadorTexto",
"entradas": [{"origem": id_carregador, "slot": 1}],
"valores": ["pessoa em um parque"]
}
id_positivo = contador_id
contador_id += 1
amostrador = {
"id": contador_id,
"tipo": "AmostradorK",
"entradas": [
{"origem": id_carregador, "slot": 0},
{"origem": id_positivo, "slot": 0},
{"origem": contador_id + 1, "slot": 0}
]
}
id_amostrador = contador_id
contador_id += 1
latente = {
"id": contador_id,
"tipo": "ImagemLatenteVazia",
"valores": [768, 768, 1]
}
conexoes.append({"origem": contador_id, "destino": id_amostrador, "slot": 3})
contador_id += 1
return {
"nos": componentes,
"conexoes": conexoes
}
# Utilização
fluxo = criar_pipeline("modeloRealistaV4")
with open("pipeline.json", "w") as arquivo:
json.dump(fluxo, arquivo, indent=2)
Soluções para Desafios Técnicos
- Depuração: Ativar pré-visualizações intermediárias e testes segmentados
- Colaboração: Versionar fluxos em JSON com convenções de nomenclatura
- Recursos: Usar VAEs leves e liberar memória manualmante
- Flexibilidade: Implementar nós de parâmetros dinâmicos e grupos lógicos