IMG2SVG
Herramienta para la conversión de imágenes rasterizadas en SVG con preprocesamiento inteligente.
El propósito de este documento es proporcionar una radiografía exhaustiva de IMG2SVG, un sistema diseñado para la conversión avanzada de imágenes rasterizadas en vectores SVG escalables. Se detallan a continuación las motivaciones, el diseño estructural y las decisiones técnicas que fundamentan la operatividad de la aplicación.
1. Utilidad y Funcionamiento General
El Problema
La digitalización de gráficos a menudo involucra lidiar con imágenes rasterizadas (mapas de bits) que sufren de pixelación y ruido, limitando su utilidad en medios de alta resolución o diseño gráfico puro. La vectorización convencional requiere herramientas de escritorio pesadas o servicios en la nube que pueden comprometer la privacidad o la inmediatez. Además, las imágenes fuente frecuentemente son granulosas, lo que provoca resultados vectorizados con miles de rutas innecesarias que degradan el rendimiento de renderizado.
La Solución Operativa
He diseñado IMG2SVG como una herramienta local (Local-First) enfocada en solucionar el paso del raster al vector de manera inmediata y privada en el navegador web.
El flujo de trabajo principal es directo:
- Carga y Selección: El usuario proporciona una imagen rasterizada mediante un panel de carga o seleccionando un archivo previamente almacenado de forma local.
- Preprocesamiento: Antes de intentar trazar los vectores, el sistema aplica filtros configurables (Box Blur, filtrado de mediana o cuantización por K-Means). Esto estabiliza el ruido y simplifica la estructura de la imagen original.
- Vectorización: La imagen es trazada y convertida a instrucciones matemáticas (SVG). Todo el proceso de cálculo intensivo se abstrae de la interfaz principal para evitar bloqueos operativos.
- Iteración Visual: El usuario manipula configuraciones y aplica los cambios. La herramienta persiste de forma local tanto el resultado como la configuración utilizada, permitiendo recuperar el trabajo exacto en sesiones posteriores.
2. Arquitectura General y Patrones Estructurales
Para asegurar un desempeño óptimo y mantener el desacoplamiento entre el núcleo computacional y la vista, he estructurado el proyecto basándome en una separación clara de responsabilidades con un enfoque en aplicaciones web progresivas (PWA) orientadas al procesamiento intensivo.
Modelo “Local-First” y Descarga Computacional
La lógica de negocio exige procesamiento intensivo (CPU-bound) en el lado del cliente. Por ello, delegué completamente la capa de preprocesamiento de píxeles y la vectorización a Web Workers.
graph TD
UI[Capa de Interfaz y Estado] -->|Envía datos y parámetros| Worker[Web Worker: imageTracerJS + Preprocesamiento]
Worker -->|Devuelve cadena SVG| UI
UI <-->|Lee / Persiste| IDB[(IndexedDB)]
El diseño previene que operaciones costosas, como el cálculo de centroides de K-Means o el trazado de rutas vectoriales, bloqueen el hilo principal (Main Thread), garantizando así una interfaz de usuario permanentemente fluida.
3. Modelado de Datos y Lógica de Estado
El estado de la aplicación se fragmenta en dos dimensiones principales: la memoria volátil para la interacción en tiempo real y la memoria persistente para el almacenamiento a largo plazo.
Almacenamiento Persistente
Utilizo IndexedDB para almacenar entidades locales sin depender de un backend externo. He definido una entidad principal, ImageRecord, que no solo almacena los binarios originales y los SVGs generados, sino también la configuración exacta utilizada.
erDiagram
ImageRecord {
number id PK
string name
Blob originalBlob
string previewUrl
string svgContent
number createdAt
number updatedAt
Object settings
}
Gestión de Estado Reactivo
El estado efímero y global de la interfaz de usuario se maneja mediante un árbol único de estado inmutable (implementado con Zustand).
classDiagram
class AppState {
+number currentImageId
+boolean processing
+number progress
+VectorizerSettings settings
+String[] detectedColors
+String[] hiddenColors
+setCurrentImageId(id)
+setProcessing(bool)
+updateSettings(settings)
}
class VectorizerSettings {
+number ltres
+number qtres
+number preprocessBlur
+number preprocessQuantize
+...
}
AppState *-- VectorizerSettings
Esta separación me permite rehidratar fácilmente la aplicación cargando un ImageRecord desde la base de datos y aplicando sus settings directamente al AppState, restaurando la sesión del usuario con exactitud.
4. Stack Tecnológico
La selección de tecnologías responde a la necesidad de equilibrar un rendimiento de alto nivel con una arquitectura mantenible y fuertemente tipada.
| Tecnología | Rol Arquitectónico | Justificación Técnica |
|---|---|---|
| Astro | Framework de enrutamiento y estructura central. | Facilita la generación de sitios estáticos con arquitectura de islas, reduciendo la carga de JavaScript en el hilo principal y habilitando PWA nativo (@vite-pwa/astro). |
| React | Construcción de UI interactiva (Componentes). | Implementado como islas (client:only="react") para gobernar únicamente la lógica dinámica compleja de vectorización e iteración visual. |
| Zustand | Gestión del estado global efímero. | Provee un mecanismo de pub/sub ultraligero que evita ciclos innecesarios de re-renderizado asociados al Context API. |
| Dexie.js | Capa de persistencia (Wrapper de IndexedDB). | Simplifica las transacciones asíncronas y facilita índices compuestos para el almacenamiento robusto de blobs en el navegador. |
| Web Workers | Aislamiento de subprocesos computacionales. | Desvía el preprocesamiento de imágenes (Median Filter, K-Means) y la invocación de imagetracerjs para liberar el Main Thread. |
| Tailwind CSS | Sistema de diseño basado en utilidades. | Permite mantener el CSS fuertemente acoplado visualmente a los componentes sin aumentar la carga cognitiva en archivos externos, asegurando adaptación a Dark Mode. |
| Biome.js | Linter y formateador unificado. | Sustituye el pipeline tradicional de ESLint/Prettier, proporcionando un análisis sintáctico más rápido (basado en Rust) para el código TypeScript. |
Cierre
La arquitectura implementada en IMG2SVG evidencia que el ecosistema web moderno es capaz de soportar aplicaciones tradicionalmente ligadas a recursos de escritorio o arquitecturas cliente-servidor pesadas. Al aprovechar Web Workers para delegar la carga computacional y aprovechar IndexedDB para construir una experiencia local-first resiliente, el sistema garantiza privacidad, desempeño y determinismo. La encapsulación del estado a través de Zustand y la segmentación asincrónica de procesos convierten una serie de tareas matemáticas intensivas en un flujo interactivo fluido y confiable para la manipulación vectorial.