Files
fn_registry/python/functions/ml/comfyui_pixelize_image_test.py
T
egutierrez e57da2f6d5 feat(gamedev): ronda 1 — pixelize + luma→alpha + export-godot (grupo gamedev)
Tres funciones CPU-only del lote gamedev 2D + 2 helpers puros + grupo de capacidad:

- comfyui_pixelize_image_py_ml (impure): Fase 2 pixelart — downscale nearest +
  cuantizacion a N colores / paleta fija (game-boy/pico-8/nes) + re-upscale nearest.
- comfyui_matting_luma_to_alpha_py_ml (impure): frame VFX sobre negro -> RGBA por
  luminancia ponderada (translucidos con additive blend).
- comfyui_export_asset_to_godot_py_pipelines (impure): puente ComfyUI -> Godot 4 —
  copia a res://assets/<dir> por kind + .import por tipo + filtro Nearest si pixelart
  + reimport headless best-effort. Compone los 2 helpers puros.
- godot_map_asset_dir_py_core, godot_clean_asset_name_py_core (pure): nucleos
  reutilizables del pipeline.
- docs/capabilities/gamedev-2d.md + INDEX: grupo nuevo gamedev.

Tests 33/33 verdes (offline PIL/numpy). Golden real verificado: asset de
~/ComfyUI/output -> /tmp/godot_test_proj con .import correcto y reimport headless
real de Godot 4.7. Sin GPU, sin red, sin tocar proyectos del usuario.

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

82 lines
2.8 KiB
Python

"""Tests de comfyui_pixelize_image (offline, sin red ni GPU; PIL/numpy)."""
import os
import sys
import numpy as np
from PIL import Image
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from ml.comfyui_pixelize_image import comfyui_pixelize_image # noqa: E402
def _noisy_png(path, w=256, h=256):
"""PNG ruidoso con cientos de colores (simula crudo borroso de IA)."""
rng = np.random.default_rng(7)
arr = rng.integers(0, 256, size=(h, w, 3), dtype=np.uint8)
Image.fromarray(arr, "RGB").save(path)
return path
def test_golden_downscale_quantize(tmp_path):
src = _noisy_png(str(tmp_path / "raw.png"))
dst = str(tmp_path / "pixel.png")
res = comfyui_pixelize_image(src, dst, downscale=8, colors=16)
assert res["ok"] is True, res["error"]
assert os.path.isfile(dst)
assert res["size"] == [256, 256] # upscale_back=True conserva tamano
assert res["n_colors_final"] <= 16 # cuantizado a <=16 colores
def test_no_upscale_back_keeps_small(tmp_path):
src = _noisy_png(str(tmp_path / "raw.png"))
dst = str(tmp_path / "small.png")
res = comfyui_pixelize_image(src, dst, downscale=8, colors=16, upscale_back=False)
assert res["ok"] is True
assert res["size"] == [32, 32] # 256//8
def test_edge_fixed_palette_game_boy(tmp_path):
src = _noisy_png(str(tmp_path / "raw.png"))
dst = str(tmp_path / "gb.png")
res = comfyui_pixelize_image(src, dst, palette="game-boy")
assert res["ok"] is True, res["error"]
assert res["n_colors_final"] <= 4 # paleta Game Boy = 4 colores
def test_edge_palette_list_hex(tmp_path):
src = _noisy_png(str(tmp_path / "raw.png"))
dst = str(tmp_path / "pal.png")
res = comfyui_pixelize_image(src, dst, palette=["#000000", "#ffffff", "#ff0000"])
assert res["ok"] is True
assert res["n_colors_final"] <= 3
def test_edge_downscale_1_only_quantizes(tmp_path):
src = _noisy_png(str(tmp_path / "raw.png"))
dst = str(tmp_path / "q.png")
res = comfyui_pixelize_image(src, dst, downscale=1, colors=8)
assert res["ok"] is True
assert res["size"] == [256, 256]
assert res["n_colors_final"] <= 8
def test_error_missing_src(tmp_path):
res = comfyui_pixelize_image(str(tmp_path / "nope.png"), str(tmp_path / "o.png"))
assert res["ok"] is False
assert "no existe" in res["error"]
def test_error_downscale_zero(tmp_path):
src = _noisy_png(str(tmp_path / "raw.png"))
res = comfyui_pixelize_image(src, str(tmp_path / "o.png"), downscale=0)
assert res["ok"] is False
assert "downscale" in res["error"]
def test_error_bad_palette(tmp_path):
src = _noisy_png(str(tmp_path / "raw.png"))
res = comfyui_pixelize_image(src, str(tmp_path / "o.png"), palette="not-a-palette")
assert res["ok"] is False
assert "paleta" in res["error"].lower()