---
name: comfyui_matting_luma_to_alpha
kind: function
lang: py
domain: ml
version: "1.0.0"
purity: impure
signature: "def comfyui_matting_luma_to_alpha(image_path: str, *, out_path: str | None = None, gamma: float = 1.0, black_point: float = 0.0, premultiply: bool = False, luma_weights: tuple = (0.299, 0.587, 0.114)) -> dict"
description: "Convierte un frame de VFX (humo, fuego, destello, magia) generado sobre fondo negro en RGBA usando la LUMINANCIA ponderada como canal alpha (brillante -> opaco, negro -> transparente). Tecnica gamedev correcta para translucidos con additive blend: preserva todo el falloff, a diferencia de un matting binario (rembg) que aplana el gradiente. Nucleo numpy puro, CPU-only: sin GPU, sin red. Devuelve {ok, out_path, size, error}. Impura solo por la lectura/escritura de disco."
tags: [comfyui, gamedev-2d, vfx, matting, alpha, luminance, ml, pil, numpy]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: "error_py_core"
imports: []
params:
  - name: image_path
    desc: "ruta del frame de entrada (generado sobre fondo negro)."
  - name: out_path
    desc: "ruta del PNG RGBA de salida; si None se escribe junto al original con sufijo '_rgba.png'. keyword-only."
  - name: gamma
    desc: "ajuste del falloff del alpha (>1 sube alpha de medios tonos, <1 lo baja). Por defecto 1.0 (lineal). keyword-only."
  - name: black_point
    desc: "piso [0,1) que limpia gris de fondo residual sin matar el efecto (re-normaliza el rango restante). Por defecto 0.0. keyword-only."
  - name: premultiply
    desc: "si True exporta RGB*alpha (materiales premultiplied / additive del motor). keyword-only."
  - name: luma_weights
    desc: "pesos (r,g,b) de la luminancia. Rec.601 (0.299,0.587,0.114) por defecto; Rec.709 = (0.2126,0.7152,0.0722). keyword-only."
output: "dict con ok (bool), out_path (str, ruta del PNG RGBA), size ([w,h]), error (str, vacio si OK)."
tested: true
tests: [test_golden_radial_glow, test_edge_all_black_is_transparent, test_edge_preserves_color, test_edge_input_rgba_recomputes_from_luma, test_edge_gamma_raises_midtone_alpha, test_edge_premultiply, test_error_missing_path]
test_file_path: "python/functions/ml/comfyui_matting_luma_to_alpha_test.py"
file_path: "python/functions/ml/comfyui_matting_luma_to_alpha.py"
---

## Ejemplo

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

# Frame de humo generado sobre negro -> RGBA listo para additive blend en Godot/Unity
res = comfyui_matting_luma_to_alpha(
    os.path.expanduser("~/ComfyUI/output/vfx_loop_00007_.png"),
    out_path="/tmp/smoke_0007_rgba.png",
    gamma=1.2,          # realza la cola tenue del humo
    black_point=0.04,   # limpia el gris residual del fondo
)
# {'ok': True, 'out_path': '/tmp/smoke_0007_rgba.png', 'size': [512, 512], 'error': ''}
```

## Cuando usarla

Tras generar frames de un efecto (humo/fuego/magia/explosion) **sobre fondo negro**
(prompt "on pure black background"), antes de montar el spritesheet o exportarlo a
un motor. Es el recorte a alpha correcto para translucidos. NO uses rembg / matting
binario para humo/fuego: rompe el degradado. Para sprites SOLIDOS (personaje, item)
con silueta definida, rembg sigue siendo lo adecuado, no esta funcion.

## Gotchas

- **El frame debe estar sobre NEGRO**: el alpha sale de la luminancia, asi que un
  fondo no-negro se vuelve parcialmente opaco. Genera con "on pure black background".
- Ignora cualquier alpha de la imagen de entrada: **recomputa** alpha desde la luma
  del RGB (un input RGBA con alpha previo se sobreescribe).
- `black_point` limpia el gris de fondo si el modelo no dio negro puro; subirlo
  demasiado come las zonas tenues del efecto.
- `premultiply=True` para materiales additive/premultiplied; deja `False` si el
  motor espera alpha straight.
- Todo error es **dict `ok=False`** (no excepcion): path inexistente, `gamma<=0`,
  `black_point` fuera de [0,1) -> `error` explica.
- CPU-only (numpy): no toca la GPU ni el servidor ComfyUI. El nodo `ImageToMask` de
  ComfyUI NO sirve para esto (hace channel-pick, no luminancia ponderada).
