--- name: image_save_png kind: function lang: py domain: ml version: "1.0.0" purity: impure signature: "def image_save_png(img: PIL.Image.Image, path: str, metadata: dict | None = None) -> str" description: "Guarda una PIL Image como PNG con metadata embebida en chunks tEXt (prompt, seed, steps, sampler, model). Crea directorio padre si no existe. Retorna path absoluto escrito." tags: [image, png, pil, pillow, metadata, save, ml, reproducibility, pendiente-usar] uses_functions: [] uses_types: [] returns: [] returns_optional: false error_type: "error_go_core" imports: [Pillow] params: - name: img desc: "imagen PIL.Image.Image a guardar" - name: path desc: "ruta de destino del archivo PNG (absoluta o relativa)" - name: metadata desc: "dict opcional de pares clave/valor a embeber en chunks tEXt del PNG para reproducibilidad (prompt, seed, steps, etc.)" output: "string: ruta absoluta del archivo PNG escrito" tested: true tests: - "crea imagen 8x8, guarda y retorna ruta absoluta" - "metadata se embebe en chunks tEXt y se puede releer con Image.text" - "sin metadata el PNG se guarda igualmente" - "crea directorio padre si no existe" - "valores numericos en metadata se convierten a str automaticamente" test_file_path: "python/functions/ml/tests/test_image_save_png.py" file_path: "python/functions/ml/image_save_png.py" --- ## Ejemplo ```python from PIL import Image from ml.image_save_png import image_save_png img = Image.new("RGB", (512, 512), color=(128, 64, 200)) path = image_save_png( img, "outputs/gen_001.png", metadata={ "prompt": "a cat on a purple sofa", "seed": 42, "steps": 20, "sampler": "euler_a", "model": "sd-v1-5", }, ) # path = "/home/lucas/.../outputs/gen_001.png" # Los metadatos quedan embebidos en el PNG y son legibles con exiftool o PIL. ``` ## Notas - Usa `PngImagePlugin.PngInfo` para chunks `tEXt` (texto plano, no comprimido). Para texto largo/comprimido existe `add_itxt`, pero `add_text` es compatible con la mayoria de lectores (exiftool, A1111, ComfyUI, etc.). - Los valores del dict se convierten a `str` automaticamente — se puede pasar int, float o bool sin castear. - Si `metadata` es `None` o `{}`, el PNG se guarda sin chunks extra (igual que `img.save(path)`). - Pillow no esta en los imports por defecto del registry para no bloquear `fn index`. Se importa lazy dentro de la funcion. - impure: escribe en disco y crea directorios.