Grayscale Studio es un estudio web para analizar y transformar imágenes en escala de grises. Carga una imagen, observa su histograma y aplica ecualización o expansión de contraste. Cada paso del cálculo queda visible: CDF, LUT y tabla de transformación.
Funciona en el navegador con OpenCV.js (WebAssembly) y Chart.js, sin backend. Está construido en Vanilla JavaScript con Web Components bajo Clean Architecture y DDD.
- Vista general
- Cómo funciona
- Características
- Inicio rápido
- Uso
- Arquitectura
- Testing y verificación
- Documentación
- Licencia
Ecualización. Original y resultado con sus histogramas. El inspector muestra la fórmula, la CDF y la tabla r → s.
Las capturas provienen del diseño en Figma, con datos de muestra calculados a partir de píxeles reales.
- Validación. OpenCV.js comprueba que la imagen (PNG, JPG o JPEG) no tenga canales de color.
- Histograma. Se extraen las frecuencias de las intensidades 0–255 y se renderiza el histograma original.
- Transformación. Se aplica una de dos operaciones:
| Operación | Tipo | Fórmula |
|---|---|---|
| Ecualización | No lineal | s = round(255 × (CDF(r) − CDFmin) / (1 − CDFmin)) |
| Expansión | Lineal | s = round(255 × (r − min) / (max − min)) |
En la ecualización, CDFmin es el primer valor acumulado no nulo. El resultado se muestra junto a la imagen original con su propio histograma y sus métricas (mínimo, máximo, media y σ).
Procesamiento
- Carga por drag & drop o selección manual de archivos.
- Validación estricta de color: una imagen con color no registra operaciones.
- Ecualización por CDF con la sustitución numérica de cada nivel.
- Expansión Min-Max con el procedimiento explicado.
Inspector matemático
- Panel de cálculo persistente con fórmula, CDF y tabla de transformación.
- Selección de intensidad con teclado y LUT completa de 256 niveles.
- Tablas de frecuencias por histograma y métricas comparativas.
Interfaz
- Estudio oscuro con superficies neutras, Poppins e IBM Plex Mono servidas localmente.
- Operación explícita: elige Ecualización o Expansión y pulsa Aplicar.
- Historial lateral con las últimas 20 operaciones en
localStorage. - Indicador de estado del motor WASM, con estados de carga, error y reintento.
- Soporte para escritorio y tablet horizontal. En tablet vertical se pide girar el dispositivo, el teléfono no es compatible y en escritorio estrecho se pide maximizar la ventana.
Requisitos: Node.js ^20.19.0 o >=22.12.0 (exigido por Vite 8).
git clone https://github.com/trinity-bytes/grayscale-studio.git
cd grayscale-studio
npm install
npm run devAbre la URL que muestra Vite (normalmente http://localhost:5173).
| Comando | Descripción |
|---|---|
npm run dev |
Servidor de desarrollo con hot reload |
npm run build |
Build de producción en dist/ |
npm run preview |
Preview del build de producción |
npm run test |
Ejecutar tests (Vitest) |
npm run test:watch |
Tests en modo watch |
- Arrastra una imagen PNG o JPG en escala de grises, o pulsa Seleccionar archivo.
- Revisa la imagen original, su histograma y sus metadatos.
- Elige Ecualización o Expansión y pulsa Aplicar. Cambiar la selección no procesa la imagen por sí solo.
- Inspecciona una intensidad, la CDF y la LUT. Inspeccionar LUT muestra los 256 niveles y Ver frecuencias muestra los datos de cada histograma.
- Usa Reemplazar para cargar otra imagen e Historial para consultar operaciones anteriores. Borrar el historial pide confirmación.
Las dependencias apuntan hacia el dominio. La infraestructura implementa los contratos del dominio, los casos de uso orquestan la lógica y el controller coordina la UI sin conocer los detalles del procesamiento.
Usuario → MainView → MainController → UseCase → Domain ← Infrastructure (OpenCV.js, Chart.js)
src/
├─ main.js # Composition root (inyección de dependencias)
├─ domain/
│ ├─ models/ # ImageModel, HistogramModel, HistogramMath (CDF, LUT, métricas)
│ └─ services/ # ImageProcessor (contrato)
├─ application/ # LoadAndValidateImage, EqualizeImage, ExpandImage
├─ infrastructure/
│ ├─ file/ # BrowserFileReader (File API)
│ ├─ opencv/ # OpenCvImageProcessor
│ └─ chart/ # ChartJsRenderer
├─ presentation/
│ ├─ views/ controllers/ # MainView, MainController
│ └─ components/ # AnalysisPanel, ErrorAlert, HistoryDrawer, ImageInfoPanel, TopNavBar, WorkspaceDropZone
└─ shared/ # Componentes base, i18n, utilidades (ScreenGuard) y estilos globales
| Tecnología | Rol |
|---|---|
| Vanilla JavaScript (ES Modules) + Web Components | Todas las capas y los componentes de UI |
| OpenCV.js | Motor de procesamiento de imagen (WebAssembly) |
| Chart.js | Histogramas y curva CDF |
| Vite | Desarrollo, bundling y build |
| CSS nativo | Tokens y estilos de componentes |
npm run test # Ejecutar una vez
npm run test:watch # Re-ejecutar al guardarLos tests cubren la matemática del dominio (CDF, LUT, métricas) y las utilidades compartidas.
Vitest no reemplaza la comparación numérica con el motor real. Para eso existe un verificador explícito que usa el fixture oficial de OpenCV.js 4.8.0, guardado fuera del repositorio:
node scripts/verify-opencv.mjs --runtime /absolute/path/to/opencv.cjsEl verificador no instala dependencias ni descarga archivos. Rechaza un fixture con un hash distinto y falla ante cualquier diferencia en píxeles o histogramas. El hash, el alcance y las instrucciones están en la verificación numérica.
- DESIGN.md: sistema visual y procedencia de los recursos.
- CHANGELOG.md: historial de versiones.
public/docs/: documentación técnica.
| Documento | Contenido |
|---|---|
| README.md | Hub principal, quick start y stack |
| arquitectura.md | Clean Architecture, DDD y SOLID |
| componentes.md | Guía de los Web Components |
| casos-de-uso.md | Casos de uso y algoritmos |
| guia-desarrollador.md | Cómo extender el proyecto |
| estilos-y-tema.md | Sistema de estilos |
| api-referencia.md | Referencia técnica de las clases |





