Files
fn_registry/python/functions/pipelines/comfyui_pixelart_real_oneshot.md
T
egutierrez c79f33265e fix(comfyui): pixelart_real_oneshot — sprite llena el frame + fondo transparente
Arregla los dos defectos reportados del pipeline comfyui_pixelart_real_oneshot:
el sujeto salía diminuto respecto al frame y siempre traía fondo (sin opción de
transparencia).

Causa raíz: comfyui_pixelize_image hacía convert("RGB") y descartaba el alpha;
comfyui_build_pixelart_workflow no inyectaba rembg (a diferencia de sus hermanos
item_icon/enemy_creature); y no había ningún paso de auto-crop al contenido.

Orden correcto del pipeline ahora:
generar (rembg) -> autocrop al bbox + cuadrar -> downscale (alpha aparte por
PixelOE) -> cuantización alpha-aware -> PNG RGBA transparente.

Piezas:
- comfyui_pixelize_image (1.1.0): keep_alpha/alpha_threshold. Con RGBA cuantiza
  solo el RGB (fondo transparente relleno con la moda del sujeto, fuera de la
  paleta) y preserva/binariza el alpha aparte. RGB sin alpha intacto.
- crop_to_content (NUEVA, pura PIL): bbox del contenido (alpha o diff-fondo) ->
  recorta -> margen -> cuadra centrando. No-throw; imagen vacía -> copia intacta.
- comfyui_build_pixelart_workflow (1.1.0): transparent=True + rembg_model.
  Inyecta nodo Image Rembg tras VAEDecode (patrón de item_icon).
- comfyui_pixelart_real_oneshot (1.1.0): transparent + autocrop + crop_pad_ratio
  + rembg_model. Recombina el alpha aparte tras PixelOE (trabaja en RGB). Campos
  nuevos: has_alpha, autocrop_applied.

Verificado en GPU (knight 64px): RGBA con 4 esquinas alpha==0, contenido cubre
88% del frame (antes 48%), 16 colores, 64x64. 32 tests offline en verde.
Report: reports/0218-2026-06-28-pixelart-sprite-fix.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 15:59:26 +02:00

11 KiB

name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, params, output, tested, tests, test_file_path, file_path
name kind lang domain version purity signature description tags uses_functions uses_types returns returns_optional error_type imports params output tested tests test_file_path file_path
comfyui_pixelart_real_oneshot pipeline py pipelines 1.1.0 impure def comfyui_pixelart_real_oneshot(subject: str, *, size: int = 64, colors: int = 16, engine: str = "pixeloe", palette=None, server: str = "127.0.0.1:8188", dest_dir: str = "~/ComfyUI/output", seed: int = 0, negative: str | None = None, mode: str = "contrast", patch_size: int = 16, thickness: int = 2, fill_frame: bool = True, transparent: bool = True, autocrop: bool = True, crop_pad_ratio: float = 0.06, rembg_model: str = "u2net", upscale_preview: int = 512, keep_base: bool = True, comfy_python: str | None = None, wait_timeout: float = 300.0, filename_prefix: str = "pixelart_real", **gen_kwargs) -> dict Pipeline one-shot prompt de texto -> sprite pixel-art REAL (grid duro + paleta limitada) en disco, con fondo transparente y sujeto que llena el frame. Materializa el metodo ganador del report 0215, ahora alpha-aware: generar a alta-res con SDXL + LoRA SDXL_pixel-art (rembg recorta el fondo si transparent), AUTOCROP al bbox del contenido + cuadrado (el sujeto llena el frame, no diminuto), downscale contrast-aware con PixelOE (engine=pixeloe, sprites; alpha recombinado aparte porque PixelOE trabaja en RGB) o nearest (tiles), y cuantizacion dura alpha-aware con comfyui_pixelize_image (16 colores libres o paleta fija pico-8/nes/game-boy). Salida PNG RGBA con transparencia real. Sweet-spot 64px personajes, 32px iconos. Fallback automatico pixeloe->nearest. Compone build_pixelart + submit + wait + fetch + crop_to_content + pixeloe_downscale + pixelize_image. Impuro: HTTP + disco.
comfyui
gamedev-2d
pixelart
pipelines
sprite
launcher
alpha
transparent
autocrop
comfyui_build_pixelart_workflow_py_ml
comfyui_submit_workflow_py_ml
comfyui_wait_result_py_ml
comfyui_fetch_output_image_py_ml
crop_to_content_py_ml
pixeloe_downscale_py_ml
comfyui_pixelize_image_py_ml
false error_py_core
comfyui_build_pixelart_workflow_py_ml
comfyui_submit_workflow_py_ml
comfyui_wait_result_py_ml
comfyui_fetch_output_image_py_ml
crop_to_content_py_ml
pixeloe_downscale_py_ml
comfyui_pixelize_image_py_ml
name desc
subject Prompt positivo (lo que se quiere ver: 'pixel art knight, full body, side view'). No puede estar vacio.
name desc
size Lado del grid final en pixeles. 64 personajes/sprites, 32 iconos/objetos simples. keyword-only.
name desc
colors Numero de colores de la paleta libre (MEDIANCUT) cuando palette es None. keyword-only.
name desc
engine 'pixeloe' (downscale contrast-aware, sujetos con silueta) o 'nearest' (downscale simple, tiles/texturas). Fallback automatico a nearest si pixeloe falla. keyword-only.
name desc
palette None (paleta libre a `colors`), nombre builtin ('pico-8', 'nes', 'game-boy') o lista de hex. Una paleta fija ignora `colors`. keyword-only.
name desc
server host:port del servidor ComfyUI (sin esquema). keyword-only.
name desc
dest_dir Directorio donde guardar los PNG (se expande ~). keyword-only.
name desc
seed Semilla del KSampler. keyword-only.
name desc
negative Prompt negativo; None usa el default de build_pixelart (evita blur/gradientes/anti-alias). keyword-only.
name desc
mode Modo de downscale de PixelOE ('contrast' SOTA, 'k-centroid', 'nearest', 'center', 'bicubic'); solo con engine='pixeloe'. keyword-only.
name desc
patch_size Tamano de patch de PixelOE (default 16). keyword-only.
name desc
thickness Grosor del outline expansion de PixelOE (default 2). keyword-only.
name desc
fill_frame Si True anade un hint de encuadre al subject para que el sujeto llene el frame (mejor detalle por pixel tras el downscale). keyword-only.
name desc
transparent Si True (default) genera con fondo recortado (rembg en el workflow) y produce sprite RGBA con transparencia real. False para tiles/texturas sin alpha (PNG opaco). keyword-only.
name desc
autocrop Si True (default) recorta la imagen base al bbox del contenido + cuadrado antes del downscale, para que el sujeto llene el frame (evita el sprite diminuto). Usa el alpha si transparent, o el color de fondo si no. keyword-only.
name desc
crop_pad_ratio Margen relativo que deja el autocrop alrededor del sujeto (0.06 = 6% del lado). keyword-only.
name desc
rembg_model Modelo Rembg para recortar el fondo ('u2net' general, 'isnet-anime' anime). Solo aplica si transparent. keyword-only.
name desc
upscale_preview Si > 0 escribe ademas un PNG re-escalado nearest a ese lado (preview con pixeles duros, p.ej. 512). 0 lo desactiva. keyword-only.
name desc
keep_base Si True conserva el PNG base de alta resolucion; si False lo borra tras pixelizar. keyword-only.
name desc
comfy_python Ruta al interprete de ComfyUI (con la lib pixeloe); None autodetecta. keyword-only.
name desc
wait_timeout Segundos maximos esperando al server. keyword-only.
name desc
filename_prefix Prefijo de los archivos de salida. keyword-only.
name desc
gen_kwargs Params extra para comfyui_build_pixelart_workflow (width, height, ckpt_name, lora_strength, use_lcm, steps, cfg, ...). keyword-only (**gen_kwargs).
dict {ok, out_path, out_path_upscaled, base_path, size, colors_final, engine_used, has_alpha, autocrop_applied, prompt_id, error}. out_path = PNG final size x size (RGBA si transparent); out_path_upscaled = preview re-escalado; has_alpha = True si lleva transparencia; autocrop_applied = True si el autocrop recorto la base; engine_used refleja el fallback (pixeloe->nearest). Si falla, ok=False y error explica en que paso. No-throw. false
python/functions/pipelines/comfyui_pixelart_real_oneshot.py

Ejemplo

# Sprite de personaje 64px: RGBA transparente + autocrop (sujeto llena el frame).
./fn run comfyui_pixelart_real_oneshot "pixel art knight, full body, centered"
import sys, os
sys.path.insert(0, os.path.join(os.environ["HOME"], "fn_registry", "python", "functions"))
from pipelines.comfyui_pixelart_real_oneshot import comfyui_pixelart_real_oneshot

# (a) Sprite personaje 64px: fondo transparente + autocrop (defaults).
res = comfyui_pixelart_real_oneshot(
    "pixel art knight, full body, centered",
    size=64, colors=16, engine="pixeloe", seed=42,
    transparent=True, autocrop=True, dest_dir="~/ComfyUI/output",
)
print(res["out_path"], res["colors_final"], res["has_alpha"], res["engine_used"])
# -> 64px RGBA, ~16 colores, has_alpha=True, esquinas transparentes, sujeto ~88% del frame

# (b) Icono 32px de un item (sprite con alpha).
res = comfyui_pixelart_real_oneshot(
    "pixel art sword icon, single object",
    size=32, colors=16, engine="pixeloe", seed=7,
)

# (c) Tile sin silueta -> nearest + paleta fija PICO-8, SIN transparencia.
res = comfyui_pixelart_real_oneshot(
    "pixel art grass texture tile, top down, seamless",
    size=64, engine="nearest", palette="pico-8",
    transparent=False, autocrop=False, fill_frame=False,
)

Cuando usarla

Cuando quieres pixel-art de verdad (grid duro + paleta limitada, verificable por conteo de colores), no la salida cruda de la difusion (que parece pixelada pero tiene decenas de miles de colores y bordes con anti-aliasing). Una sola llamada hace generar -> recortar -> downscale -> cuantizar. Para sprites de sujeto (personajes, criaturas, objetos) deja los defaults transparent=True + autocrop=True: salen RGBA con fondo transparente y el sujeto llena el frame. Usa engine="pixeloe" para conservar la silueta. Para tiles/texturas/fondos sin contorno usa engine="nearest", transparent=False, autocrop=False (mas barato, CPU puro, sin alpha). 64px es el sweet-spot de personajes; 32px solo para iconos/objetos simples.

Gotchas

  • Impuro: requiere el servidor ComfyUI vivo en server (default 127.0.0.1:8188) y los modelos instalados (SDXL Juggernaut + LoRA SDXL_pixel-art + SDXL_lcm-lora). Si esta caido, falla en submit con ok=False y el error de conexion (nunca lanza).
  • engine="pixeloe" necesita la lib pixeloe, que vive en el venv de ComfyUI (no en el del registry). pixeloe_downscale hace el puente de interprete automaticamente; si no la encuentra, el pipeline cae a nearest y lo reporta en engine_used + error (no aborta).
  • El nodo PixelOEPixelize+ de ComfyUI_essentials estaba roto por un import obsoleto (pixeloe.pixelize -> ahora pixeloe.legacy.pixelize); por eso el pipeline usa la lib directa via pixeloe_downscale, no el nodo del server.
  • dest_dir es un directorio (se crea si no existe). Los nombres de salida son <prefix>_<size>px_<engine>_<paleta|qN>.png y ..._up.png (preview).
  • Una paleta fija (pico-8/nes/game-boy/lista hex) ignora colors y puede dar menos colores que colors si el sujeto no cubre toda la paleta.
  • Encuadre: si el sujeto ocupa poca area del frame, a 64/32px queda diminuto. Dos mecanismos lo evitan: fill_frame=True (hint al prompt) y, sobre todo, autocrop=True (default) que recorta al bbox real del contenido + cuadrado tras generar. Con autocrop el sujeto llena ~85-90% del frame aunque el prompt no lo encuadre perfecto.
  • transparencia (v1.1.0): transparent=True (default) mete el nodo Image Rembg en el workflow (requiere ese custom node en el server) y produce PNG RGBA. Las 4 esquinas salen alpha==0. Para tiles/fondos opacos: transparent=False.
  • alpha a traves de PixelOE: PixelOE trabaja en RGB y pierde el alpha; el pipeline downscalea el alpha del recorte por separado (nearest al mismo size) y lo recombina sobre el grid antes de cuantizar. Por eso el sprite final conserva la transparencia con engine="pixeloe".
  • Si la generacion sale toda transparente (rembg no detecto sujeto), no crashea: el autocrop deja la imagen sin recortar y el resto del pipeline sigue (sprite vacio, colors_final bajo). Revisa el subject en ese caso.
  • No reintenta el sampler: para mejor toma, varia seed.

Capability growth log

  • v1.1.0 (2026-06-28) — sprite-fix: transparent/autocrop/crop_pad_ratio/ rembg_model. Arregla los 2 bugs reportados: (1) sprite diminuto -> autocrop al bbox del contenido + cuadrado antes del downscale (sujeto pasa de ~48% a ~88% del frame); (2) sin transparencia -> rembg en el workflow + cuantizacion alpha-aware + alpha recombinado tras PixelOE -> PNG RGBA con esquinas alpha==0. Anade crop_to_content a la composicion. Verificado en GPU (knight 64px).
  • v1.0.0 (2026-06-28) — pipeline inicial. Materializa el metodo ganador del report 0215 (PixelOE contrast downscale -> cuantizacion dura). Compone build_pixelart + submit + wait + fetch + pixeloe_downscale + pixelize_image (issue 0087).