Por qué toda imagen que subes a LUVI acaba en JPEG o PNG

Las fotos HEIC del iPhone fallaban en Chrome, el WebP confundía a la mitad de los modelos y un decodificador en el navegador tardaba 27 segundos con 12 megapíxeles. Movimos la conversión al servidor con una regla: toda imagen se guarda como JPEG o PNG, con color y orientación intactos.

Publicado:

Decenas de tarjetas translúcidas de colores atraviesan un punto de luz índigo y salen convertidas en dos fichas: una blanca brillante y otra con un damero transparente.

Subir imágenes parece la parte aburrida de una plataforma de generación. Para nosotros era la fuente más persistente de correos de soporte. Esto es lo que fallaba, lo que probamos y la regla que lo arregló.

¿Qué estaba fallando?

HEIC. Todos los iPhone lo usan por defecto. Safari sabe decodificarlo; Chrome y Firefox, no, así que quien subía una foto del celular desde Chrome recibía un error o un archivo que ningún modelo aceptaba.

WebP y AVIF. A los navegadores les encantan; a los proveedores de modelos, no. Varios modos los rechazaban de plano, y otros los aceptaban y fallaban después sin avisar.

Orientación y color. Una foto hecha de lado lleva una etiqueta de rotación que unos decodificadores respetan y otros ignoran; una foto de iPhone lleva un perfil de color Display P3 que, si se pierde en la conversión, deja la imagen apagada.

¿Por qué no convertir en el navegador?

Lo evidente era convertir en el navegador antes de subir. Publicamos un decodificador HEIC en WebAssembly y murió el mismo día: la librería compila su worker con new Function, algo que nuestra política de seguridad de contenido —la que protege la aplicación de los scripts inyectados— no permite. Cada subida de HEIC desde Chrome lanzaba un EvalError.

La versión de la librería compatible con esa política sí funcionaba, pero una foto de 12 megapíxeles tardaba 27 segundos en decodificarse en una computadora portátil. El mismo archivo tarda 1.4 segundos en el servidor. Y, además, el HEIC era más pequeño que el JPEG resultante, así que convertir en el dispositivo tampoco ahorraba ancho de banda. Quitamos el decodificador del navegador.

¿Cuál es la regla ahora?

Toda imagen se guarda como JPEG o PNG. El formato se lee de los bytes, nunca del nombre del archivo ni del tipo de contenido: un JPEG llamado .png se guarda como JPEG. Las subidas en JPEG y PNG se conservan byte a byte. Todo lo demás se convierte en el servidor:

  • PNG si algún píxel es transparente, para que nada se aplane sobre un fondo.
  • JPEG con calidad 92 y croma completo en el resto de los casos.
  • Se aplica la rotación EXIF, así que la imagen guardada está derecha.
  • El perfil de color incrustado se conserva; una imagen Display P3 de iPhone sale como se veía en el celular.
  • Un GIF o un WebP animado conserva su primer fotograma; un SVG se rasteriza a 2,048 px en su lado largo.

La pila de decodificación es concreta: una librería para WebP, GIF, AVIF, TIFF y SVG; un decodificador dedicado para HEIC (el genérico solo entiende la variante AV1); y un pequeño lector de BMP, porque la librería de imagen no trae ninguno. ICO, PSD y JPEG XL no se pueden convertir y se rechazan con un mensaje claro.

¿Dónde se ejecuta la conversión?

Todas las entradas pasan por la misma función: el cuadro de subida, la subida por URL, la ruta directa al almacenamiento que usan los archivos grandes y el ticket de subida del conector para Claude. Cuando un archivo ya está en el almacenamiento, se vuelve a leer, se convierte, se escribe con su nuevo nombre y solo entonces se elimina el original. La respuesta de la subida te dice el nombre del archivo guardado y desde qué formato se convirtió.

¿Qué cambia para ti?

Las fotos del celular se suben desde cualquier navegador. Cada modelo recibe un formato que acepta. Las descargas son archivos que abre cualquier aplicación. Y la conversión tarda alrededor de un segundo, en nuestro lado y una sola vez.

Los límites, como referencia: imágenes de hasta 50 MB; video, audio, 3D y PDF de hasta 1 GB. La lista completa de formatos aceptados está en el centro de ayuda: ¿qué formatos y tamaños de archivo puedo subir? y ¿por qué mi HEIC o WebP se ha convertido en JPEG?.

Preguntas

¿Pierdo calidad?

Las subidas en JPEG y PNG se guardan byte a byte. El resto de formatos se recodifica una sola vez y a alta calidad: PNG si hay transparencia y, si no, JPEG con calidad 92 y sin submuestreo de croma.

¿Por qué no conservar también el HEIC?

Porque nada de lo que viene después lo lee de forma fiable: la mayoría de los modelos lo rechaza y los navegadores no se ponen de acuerdo. El archivo convertido es el que pueden usar todos los modelos, todos los navegadores y cualquier descarga.

¿Qué se sigue rechazando?

ICO, PSD y JPEG XL. Guárdalos antes como JPG o PNG.

Más de Dentro de LUVI