Files
fn_registry/python/functions/ml/pixeloe_downscale.md
T
egutierrez ccdd529bdc feat(comfyui): pipeline comfyui_pixelart_real_oneshot — pixelart REAL (PixelOE + cuantizacion dura)
Materializa el metodo ganador del report 0215: generar a alta-res con SDXL +
LoRA SDXL_pixel-art, downscale contrast-aware con PixelOE (engine=pixeloe para
sprites/personajes) o nearest (tiles), y cuantizacion dura con
comfyui_pixelize_image (16 colores libres o paleta fija pico-8/nes/game-boy).

- pixeloe_downscale_py_ml: downscale contrast-aware via lib pixeloe con bridge
  de interprete (la lib vive en el venv de ComfyUI, no en el del registry).
  No-throw, fallback limpio si pixeloe no disponible.
- comfyui_pixelart_real_oneshot_py_pipelines: one-shot que compone build_pixelart
  + submit + wait + fetch + pixeloe_downscale + pixelize_image. Fallback
  automatico pixeloe->nearest. Sweet-spot 64px personajes, 32px iconos.

Verificado por PIL: personaje 64x64=16 colores, icono 32x32=16 colores (vs ~33k
de la imagen de difusion cruda). 100% grid duro + outline nitido.

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

5.6 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
pixeloe_downscale function py ml 1.0.0 impure def pixeloe_downscale(src_path: str, dst_path: str, *, mode: str = 'contrast', target_size: int = 64, patch_size: int = 16, thickness: int = 2, color_matching: bool = True, no_upscale: bool = True, comfy_python: str | None = None) -> dict Downscale contrast-aware (Contrast-Aware Outline Expansion de Kohaku, lib `pixeloe`) que colapsa una ilustracion a un grid de pixel-art pequeno (64 personajes, 32 iconos) conservando contornos/silueta. Es la etapa de downscale del metodo SOTA de pixel-art (report 0215). NO cuantiza la paleta (eso lo hace despues comfyui_pixelize_image). Resuelve el gotcha de que `pixeloe` solo vive en el venv de ComfyUI con un 'bridge' de interprete: si falta en el interprete actual, re-ejecuta su nucleo por subprocess con el python de ComfyUI. No-throw: todo error viaja en `error`. Determinista; impura por I/O de disco + subprocess. Devuelve {ok, out_path, size, mode, target_size, via, error}.
comfyui
gamedev-2d
pixelart
ml
pixeloe
downscale
contrast-aware
image
bridge
false error_py_core
name desc
src_path ruta de la imagen de entrada (PNG/JPG/...). Si no existe -> ok=False con error.
name desc
dst_path ruta del PNG de salida; se crea el directorio padre si falta.
name desc
mode algoritmo de downscale de pixeloe: 'contrast' (SOTA, conserva silueta), 'bicubic', 'nearest', 'center' o 'k-centroid'. keyword-only.
name desc
target_size lado del grid resultante en pixeles (64 para personajes, 32 para iconos). keyword-only.
name desc
patch_size tamano del patch que pixeloe colapsa por celda del grid. keyword-only.
name desc
thickness grosor de la expansion de contorno (outline expansion). keyword-only.
name desc
color_matching corrige el color de cada celda contra el original si True. keyword-only.
name desc
no_upscale True devuelve el grid real target_size x target_size (lo habitual, para luego cuantizar); False re-escala al tamano original con pixeles duros (preview). keyword-only.
name desc
comfy_python ruta a un interprete con `pixeloe` para el bridge cuando el actual no la tiene. Si None: COMFY_PYTHON y luego ~/ComfyUI/.venv/bin/python3. keyword-only.
dict con ok (bool), out_path (str), size ([w,h] de la imagen escrita), mode (str usado), target_size (int pedido), via ('inproc' si pixeloe estaba en este interprete, 'bridge' si se delego por subprocess) y error (str, vacio si OK). No lanza excepciones. true
test_golden_downscale_64_or_clean_degrade
test_edge_target_size_32
test_edge_mode_nearest_no_color_matching
test_error_missing_src_no_throw
test_error_no_interpreter_with_pixeloe
python/functions/ml/pixeloe_downscale_test.py python/functions/ml/pixeloe_downscale.py

Ejemplo

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

# Colapsa el render del caballero (1024x1024) a un grid de pixel-art 64x64
# conservando la silueta. NO cuantiza paleta todavia.
res = pixeloe_downscale(
    os.path.expanduser("~/ComfyUI/output/pixel_compare/knight_base_00001_.png"),
    "/tmp/knight_grid64.png",
    mode="contrast", target_size=64, no_upscale=True,
)
# {'ok': True, 'out_path': '/tmp/knight_grid64.png', 'size': [64, 64],
#  'mode': 'contrast', 'target_size': 64, 'via': 'bridge', 'error': ''}

# Despues: dureza de color (cuantizacion) con la funcion hermana.
from ml.comfyui_pixelize_image import comfyui_pixelize_image
comfyui_pixelize_image("/tmp/knight_grid64.png", "/tmp/knight_q16.png",
                       downscale=1, colors=16, upscale_back=False)

Cuando usarla

Primera etapa del metodo SOTA de pixel-art: cuando ya tienes una ilustracion (render SDXL/Flux, sprite, foto) y quieres reducirla a un grid de pixel-art chico sin perder los contornos (lo que arruina un resize NEAREST/lanczos normal). Usala antes de la cuantizacion dura de paleta con comfyui_pixelize_image (paso de color). target_size 64 para personajes, 32 para iconos. Si solo necesitas el resize+cuantizado rapido sin contornos finos, comfyui_pixelize_image sola basta; para el resultado ganador, encadena pixeloe_downscale -> comfyui_pixelize_image.

Gotchas

  • pixeloe solo esta en el venv de ComfyUI (~/ComfyUI/.venv), no en el del registry. La funcion lo resuelve con un bridge: si import pixeloe falla, re-ejecuta su nucleo por subprocess con el python de ComfyUI. El campo via dice si fue inproc o bridge.
  • El modulo es pixeloe.legacy.pixelize, no pixeloe.pixelize (ruta vieja eliminada).
  • El nodo PixelOEPixelize+ de ComfyUI_essentials estaba roto por ese cambio de import; por eso aqui se llama la lib directa (numpy + PIL, sin cv2).
  • NO cuantiza la paleta: el resultado conserva muchos colores; la dureza retro la aplica despues comfyui_pixelize_image. No esperes pocos colores en la salida.
  • No-throw: src inexistente, pixeloe ausente en todos los interpretes, o subprocess caido -> ok=False con error explicado, nunca excepcion. El pipeline llamante hace fallback mirando ok.
  • Resolucion del interprete del bridge: arg comfy_python -> env COMFY_PYTHON -> ~/ComfyUI/.venv/bin/python3 (el primero que exista como archivo).
  • no_upscale=True (default) devuelve el grid real target_size x target_size; con False vuelve al tamano original con pixeles duros (preview), no el grid pequeno.