Skip to content

Methodology

Metodología de formatos de imagen

Canvas API + codificadores nativos del navegador. La imagen nunca sale de tu dispositivo.

By Published

El clúster de Imagen convierte entre PNG, JPG y WebP usando la Canvas API nativa del navegador. No hay paso de carga, no hay procesamiento del lado del servidor y no hay servicio de imágenes de terceros en el proceso — lo que tiene implicaciones tanto para la privacidad como para la calidad.

El proceso de conversión

  1. El usuario selecciona un archivo mediante arrastrar y soltar o el selector de archivos.
  2. El archivo se lee como un ImageBitmap a través de createImageBitmap(file).
  3. Se crea un canvas fuera de pantalla con las dimensiones nativas del bitmap.
  4. El bitmap se dibuja en el canvas.
  5. El canvas se exporta mediante canvas.toBlob(callback, mimeType, quality) — la calidad solo aplica a objetivos con pérdida.
  6. El Blob resultante se ofrece como descarga.

Cada paso se ejecuta en el navegador. El archivo no se envía a ningún lugar — no hay fetch, no hay FormData, no hay carga XHR. Lo mismo aplica a la herramienta Imagen a Base64, que usa la FileReader API en lugar del canvas pero sigue el mismo principio de solo navegador.

Gestión de calidad

Sin pérdida → con pérdida (PNG/WebP → JPG)

Al pasar de un formato sin pérdida a JPG, exponemos un deslizador de calidad (por defecto 0,85) que controla la agresividad de cuantización del codificador JPG. Con 0,85, el archivo es típicamente un 80-95 % más pequeño que el PNG fuente sin diferencia visual perceptible para fotografías. Por debajo de 0,7, los artefactos se vuelven visibles; limitamos el mínimo a 0,5 para evitar producir accidentalmente resultados visiblemente degradados.

Con pérdida → sin pérdida (JPG → PNG)

Pasar de JPG a PNG no restaura la calidad que el JPG ya descartó. La salida es bit a bit exacta de lo que el JPG decodificó, pero las pérdidas de redondeo del JPG están incorporadas. Esto rara vez es útil en la práctica; el camino mejor es encontrar una fuente de mayor calidad.

Con pérdida → con pérdida (JPG → WebP, etc.)

Cada guardado con pérdida introduce nuevos errores de cuantización sobre los existentes de la fuente. Para archivos que ya han pasado por varios guardados, esto puede causar una degradación compuesta visible. Siempre recodifica desde la fuente de mayor calidad que tengas.

Lo que no manejamos

  • HEIC / HEIF. El formato por defecto de Apple desde iOS 11. El soporte del navegador es prácticamente nulo fuera del ecosistema de Apple, por lo que necesitaríamos incluir un decodificador de más de 1 MB. No vale la pena.
  • Formatos RAW (DNG, CR2, NEF, ARW). El mismo problema — decodificadores pesados para una audiencia pequeña. Usa Lightroom / darktable / RawTherapee.
  • SVG ↔ rasterizado. Posible a través del canvas, pero vector → rasterizado pierde escalabilidad y el proceso inverso pierde fidelidad. Es una conversación diferente.
  • Conversión por lotes. Nuestra interfaz maneja un archivo a la vez. Para uso por lotes, usa el endpoint REST o una herramienta de escritorio.

El proceso del codificador, en código

La conversión es lo suficientemente corta como para escribirla. Dado un File de una entrada de archivo, el proceso completo se ejecuta en unas seis líneas:

const bitmap = await createImageBitmap(file);
const canvas = new OffscreenCanvas(bitmap.width, bitmap.height);
const ctx = canvas.getContext("2d");
ctx.drawImage(bitmap, 0, 0);
const blob = await canvas.convertToBlob({ type: "image/webp", quality: 0.85 });
// blob es la salida convertida, lista para descargar

Cada paso es nativo del navegador: createImageBitmap decodifica el formato fuente (definido en el HTML Living Standard), OffscreenCanvas proporciona una superficie de dibujo sin renderizado, y convertToBlob invoca el codificador WebP / JPEG / PNG integrado del navegador con el parámetro de calidad definido en la especificación (0-1 para formatos con pérdida, ignorado para PNG). El mismo codificador es el que Chrome usa para guardar canvases a través de toDataURL; simplemente enrutamos el resultado a una descarga en lugar de a una cadena. No hay WASM, no hay biblioteca de terceros y no hay llamada de red — todo el proceso se ejecuta en aproximadamente 40-200 ms para una entrada 4K en un portátil de 2023, con el cuello de botella desplazándose entre decodificación (fuentes PNG) y codificación (salidas WebP a quality 0,85+).

Supuestos y limitaciones

  • Un archivo a la vez. La interfaz acepta un solo archivo por sesión. La recodificación masiva necesita un script contra la REST API o una herramienta de escritorio.
  • Codificadores nativos del navegador.La calidad de salida depende del navegador del usuario. El codificador WebP de Chromium es libwebp; Firefox usa el suyo. Existen sutiles diferencias de artefactos por motor a calidad < 0,7.
  • Sin decodificación HEIC/HEIF/RAW. Las entradas en esos formatos no se pueden abrir a través de createImageBitmap en la mayoría de los navegadores sin un shim WASM que no distribuimos.
  • Sin codificación AVIF. La lectura está soportada en navegadores modernos; la escritura requiere WASM (libaom), lo que empujaría el paquete más allá del tamaño aceptable.
  • Sin pérdida ↔ con pérdida es unidireccional. Recodificar un JPG a PNG no restaura información; el PNG recodificado es bit a bit exacto del JPG decodificado, con sus pérdidas de cuantización incorporadas.
  • Perfil ICC solo conservado para reescrituras del mismo formato. La conversión entre formatos (PNG → JPG) puede eliminar el perfil ICC incrustado según la implementación del navegador.
  • Límite de memoria. Las entradas muy grandes (40+ megapíxeles) pueden causar errores de memoria en Safari móvil.

Soporte mínimo de navegadores

La codificación WebP a través de canvas.toBlob requiere Chromium 23+, Firefox 65+, Safari 14+, Edge 79+. A fecha de 2026, eso cubre más del 97 % del tráfico global. La codificación AVIF no está soportada en la Canvas API del navegador; necesitaríamos un codificador WASM para ofrecer ese objetivo, que es material para la hoja de ruta.

Frequently asked questions

¿Cómo convierte Convertitive entre formatos de imagen?
El proceso: (1) cargar el archivo fuente en un elemento Image del navegador; (2) dibujarlo en un Canvas HTML con las dimensiones objetivo; (3) llamar a canvas.toBlob(callback, mimeType, quality) con el formato y parámetro de calidad deseados. El códec integrado del navegador gestiona la codificación real. Esto significa que el soporte de formato depende del dispositivo: la decodificación WebP requiere Chrome/Firefox/Edge (Safari 14+); AVIF requiere Chrome 85+/Firefox 93+.
¿Qué algoritmo de compresión usa el codificador JPEG?
JPEG usa compresión con pérdida de Transformada Discreta del Coseno (DCT) según se especifica en ISO/IEC 10918-1:1994 (línea base JPEG). El parámetro de calidad del codificador del navegador se asigna a la escala de la tabla de cuantización DCT — quality=1.0 usa cuantización mínima (casi sin pérdida), quality=0 usa cuantización máxima (muy comprimido). Las tablas de cuantización exactas son específicas de la implementación según la especificación HTML canvas.toBlob() (WHATWG HTML §15.4.13).
¿La conversión de imagen es sin pérdida para PNG a PNG?
PNG usa compresión sin pérdida DEFLATE (RFC 2083, §2.1). Recodificar un PNG a través de la Canvas API vuelve a ejecutar DEFLATE, lo que puede producir un archivo más grande o más pequeño que el original según la implementación DEFLATE del navegador y la configuración del nivel de compresión. Los valores de píxel son idénticos; solo cambia el tamaño del archivo comprimido. Los datos del canal alfa se conservan exactamente.
¿La imagen sale de mi dispositivo?
No. Todo el procesamiento de imágenes usa la Canvas API del navegador y la FileReader API — JavaScript del lado del cliente puro sin solicitudes al servidor. La pestaña Red en las herramientas de desarrollo del navegador muestra cero solicitudes salientes al convertir imágenes. Esto es verificable de forma independiente; el código fuente es público en github.com/convertitive.
¿Cuáles son las limitaciones de precisión y calidad del conversor de imágenes?
Tres limitaciones: (1) perfil de color: Canvas dibuja imágenes en el espacio de color interno del navegador (sRGB en la mayoría de los dispositivos), por lo que los perfiles ICC incrustados en las imágenes fuente pueden descartarse; (2) EXIF/metadatos: canvas.toBlob() elimina todos los metadatos EXIF, IPTC y XMP — orientación, GPS, modelo de cámara se pierden; (3) la calidad es subjetiva — el parámetro de calidad se asigna de forma diferente en las implementaciones de codificadores JPEG y WebP de distintos navegadores, por lo que un JPEG quality=0.8 de Chrome puede diferir en tamaño y apariencia del generado por Firefox con el mismo ajuste.

Related

Published May 14, 2026