CreaRack-SL

Import Visio: masters con arte EMF incrustado (Cisco) → PNG renderizable

Descripción

Regresión del import Visio detectada en PROD el 2026-07-13: los stencils de Cisco (Catalyst 9000) no se renderizan tras la importación. La causa: Cisco no dibuja sus masters con geometría Visio, sino que incrusta el arte en un formato bitmap nativo de Windows (EMF — Enhanced Metafile). libvisio-ng lo envuelve tal cual en un <image href="data:image/emf;base64,...">, que ningún navegador web renderiza.

Impacto observado

  • 165/165 masters del Catalyst 9000: solo-EMF (sin geometría vectorial).
  • Miniaturas en el modal de stenciles: icono de imagen rota.
  • Stencil importado en el editor: vacío (sin puerto ni serigrafía).

Solución (v1.54.1)

Detección (svg_is_emf_only())

Antes de procesar cada SVG generado por libvisio-ng, se detecta:

  • Presencia de data:image/emf;base64,....
  • Ausencia de cualquier geometría vectorial (<path>, <rect>, <line>, <polyline>, <polygon>, <ellipse>, <circle>, <text>).

Un SVG es “solo-EMF” si cumple ambas condiciones. Los SVGs con geometría real (Eaton) no son detectados y continúan sin cambios.

Conversión (convert_emf_only_svgs())

  1. Extracción de EMF: Los datos base64 se decodifican en ficheros .emf temporales.
  2. Lote 1 (EMF → SVG vectorial):
    LibreOffice en modo headless convierte TODOS los EMF en una sola invocación (el arranque de LO es el coste; por fichero sería minutos). Resultado: SVGs vectoriales de mejor calidad.
  3. Rasterizado (SVG → PNG):
    rsvg-convert a 2400 px de ancho (nítido en el modal).
  4. Lote 2 (EMF → PNG directo, fallback):
    Si rsvg falló, LibreOffice convierte directamente EMF→PNG (menor calidad, pero visible).
  5. Postproceso Pillow (_postprocess_stencil_png()):
    • Blanco → transparente (ImageChops, en C).
    • Autocrop por alpha.
    • Escalado mínimo (800 px) si cabe.

Desaprobación

  • Un master solo-EMF cuya conversión falle se descarta con un warning en logs.
  • Mejor ausente en la librería que una miniatura rota en el UI.

Cambios de configuración

  • compose.yml (dev): memoria 512M → 1024M.
    libvisio_ng.convert() pica ~515 MB de RSS al procesar un .vss de fabricante de 40 MB. El kernel OOM-killaba con 512M. PROD no limita memoria.

QA

  • Tests unitarios: detección de SVG solo-EMF, conversión a PNG, descarte de fallidos.
  • Suite manual QA_VISIO (tests/qa/test_visio_real_vendor_files.py):
    • Opt-in explícito: QA_VISIO=1 (no corría en pre-push por default porque tumba el container).
    • Guardia de memoria: si el container tiene <900 MB, se salta con aviso (en lugar de OOM).
    • Prueba real: Cisco Catalyst 9000 (165 masters, 40 MB).
    • Resultado esperado: ≥90% convertidos a PNG, todos visible (sin solo-EMF sin convertir).

Verificación visual

  • Catalyst 9200/9300: nítidos, con puertos y serigrafía.

Limitaciones

  • Los stencils rotos importados antes del fix no se auto-reparan.
    Solución: borrarlos de la librería y re-importar el fichero .vss.

Véase también

  • [[entity—racks—service—emf-converter]]
  • [[entity—racks—function—svg-is-emf-only]]
  • [[entity—racks—model—stencil]]
  • [[concept—ux—import-wizard]]
  • [[decision—20260713—visio-emf-detection-and-fallback]]