Files
fn_registry/python/functions/ml/comfyui_pixelize_image.md
T
egutierrez a27dcc028c docs(capabilities): unifica tag gamedev en gamedev-2d + separa gamedev-engine
El doctor reportaba el dominio gamedev en doble FAIL: el tag plano `gamedev`
(44 funciones) como `ungrouped_candidate` y la pagina `gamedev-2d.md` como
`doc_orphan`. Causa raiz: el INDEX declaraba `[gamedev](gamedev-2d.md)` y el
auditor solo registra el slug cuando label==target, asi que ni casaba la
pagina ni declaraba el tag.

Al revisar las 44 funciones habia dos clusters reales bajo el mismo tag, asi
que se separan en dos grupos honestos:

- gamedev-2d (tag canonico): 31 builders de workflow ComfyUI + 5 de apoyo
  (post-proceso + puente a Godot) = 36. Se elimina el tag plano `gamedev` de
  los builders (ya tenian `gamedev-2d`) y se reemplaza por `gamedev-2d` en las
  de apoyo.
- gamedev-engine (grupo nuevo, pagina madre nueva): runtime de juego C++
  multiplataforma (SDL3 + sokol_gfx + miniaudio, Issue 0072b) = 8. Game loop,
  camara 2D, input unificado, sprite batch, setup render/audio, build wasm.

El tag plano `gamedev` queda eliminado (count 0). INDEX corregido: fila
gamedev-2d con label==target y conteo 36 + fila nueva gamedev-engine (8).

Verificacion: `fn index` + `fn doctor capabilities` -> ambos grupos OK
(declared_in_index=yes, doc_exists=yes, sin issues); `gamedev` plano = 0.
Solo se modifico el campo `tags` de los .md, ningun archivo de codigo.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 02:40:50 +02:00

4.5 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_pixelize_image function py ml 1.0.0 impure def comfyui_pixelize_image(src_path: str, dst_path: str, *, downscale: int = 8, colors: int = 16, palette=None, dither: bool = False, upscale_back: bool = True) -> dict Post-proceso pixel-perfect (Fase 2 pixelart): imagen -> downscale nearest-neighbor por factor (colapsa cada bloque borroso a un pixel duro) -> cuantizacion a N colores (MEDIANCUT) o a una paleta fija embebida (game-boy / pico-8 / nes / lista de hex) -> opcional re-upscale nearest conservando los pixeles duros. Convierte el 'pixelart borroso de IA' en pixelart de verdad. Nucleo PIL puro, CPU-only: sin GPU, sin red. Devuelve {ok, out_path, size, n_colors_final, error}. Impura solo por la lectura/escritura de disco.
comfyui
gamedev-2d
pixelart
ml
pil
quantize
palette
image
false error_py_core
name desc
src_path ruta de la imagen de entrada (PNG/JPG/...).
name desc
dst_path ruta del PNG de salida (se crea el directorio si falta).
name desc
downscale factor entero de reduccion nearest (>=1); cada bloque downscale x downscale px colapsa a 1 pixel. 1 = solo cuantiza sin colapsar el grid. keyword-only.
name desc
colors numero de colores objetivo (2..256) cuando palette es None; cuantizacion MEDIANCUT determinista. keyword-only.
name desc
palette None (auto a 'colors'), nombre de paleta fija builtin ('game-boy','pico-8','nes') o lista de hex ('#rrggbb'/'rrggbb'). Una paleta fija ignora 'colors'. keyword-only.
name desc
dither aplica Floyd-Steinberg al cuantizar (off por defecto = pixelart limpio). keyword-only.
name desc
upscale_back re-escala nearest al tamano original (preview con pixeles duros). False deja la imagen pequena. keyword-only.
dict con ok (bool), out_path (str), size ([w,h] de la imagen final), n_colors_final (int, colores distintos del resultado), error (str, vacio si OK). true
test_golden_downscale_quantize
test_no_upscale_back_keeps_small
test_edge_fixed_palette_game_boy
test_edge_palette_list_hex
test_edge_downscale_1_only_quantizes
test_error_missing_src
test_error_downscale_zero
test_error_bad_palette
python/functions/ml/comfyui_pixelize_image_test.py python/functions/ml/comfyui_pixelize_image.py

Ejemplo

import sys, os
sys.path.insert(0, os.path.join(os.environ["HOME"], "fn_registry", "python", "functions"))
from ml.comfyui_pixelize_image import comfyui_pixelize_image

# Crudo SDXL+pixel-art-xl 1024x1024 -> pixelart 16 colores, grid de 128
res = comfyui_pixelize_image(
    os.path.expanduser("~/ComfyUI/output/pixelart_00001_.png"),
    "/tmp/hero_pixel.png",
    downscale=8, colors=16,
)
# {'ok': True, 'out_path': '/tmp/hero_pixel.png', 'size': [1024, 1024], 'n_colors_final': 16, 'error': ''}

# Forzar la paleta retro Game Boy (4 colores) y dejar la imagen pequena (sin upscale)
comfyui_pixelize_image("/tmp/hero_pixel.png", "/tmp/hero_gb.png",
                       palette="game-boy", upscale_back=False)

Cuando usarla

Fase 2 del pipeline pixelart: tras generar el crudo (SDXL + LoRA pixel-art-xl), para colapsar el grid borroso a pixeles duros y limitar la paleta. Tambien sirve para "pixelizar" cualquier imagen (sprite, render, foto) a estetica retro sin tocar la GPU. Para llevar el resultado a Godot con filtro Nearest: comfyui_export_asset_to_godot(out, "pixelart", proj).

Gotchas

  • nearest, no lanczos: el downscale usa NEAREST a proposito; interpolar suave re-difumina el grid. No lo cambies por "calidad".
  • palette fija (game-boy/pico-8/nes o lista de hex) ignora colors. La paleta se rellena internamente repitiendo su ultimo color para que quantize no introduzca un negro extra por entradas vacias (bug arreglado en v1.0.0).
  • downscale con upscale_back=False deja la imagen de w//downscale x h//downscale: util para spritesheets compactos; con True vuelve al tamano original con bordes duros (preview).
  • Todo error es dict ok=False (no excepcion): src_path inexistente, downscale<1, paleta desconocida -> error explica. No crashea ni borra nada.
  • n_colors_final cuenta colores distintos reales del PNG escrito; con paleta fija puede ser menor que el tamano de la paleta si la imagen no usa todos.
  • CPU-only: no toca la GPU ni el servidor ComfyUI; corre en cualquier interprete con Pillow.