Funcionalidadactivecreado Mon Jul 13#stencils#visio#import-wizard#rasterization#emf#png#liboffice#racks
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())
- Extracción de EMF: Los datos base64 se decodifican en ficheros
.emftemporales. - 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. - Rasterizado (SVG → PNG):
rsvg-converta 2400 px de ancho (nítido en el modal). - Lote 2 (EMF → PNG directo, fallback):
Si rsvg falló, LibreOffice convierte directamente EMF→PNG (menor calidad, pero visible). - 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).
- Opt-in explícito:
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]]