Pillow, ffmpeg y sips: el perfil de color se pierde según el formato
Una prueba sobre la misma imagen Display P3 compara cómo guardan JPG, PNG y WebP tres herramientas habituales. ffmpeg y Pillow fallan en direcciones opuestas y subir la calidad no cambia nada.

Pillow 11.3, ffmpeg 7.1 y el sips de macOS no tratan igual el perfil de color incrustado, y el resultado cambia según el formato de salida. Con la misma foto Display P3 como entrada, ffmpeg conserva el perfil en JPG y PNG y lo pierde en WebP; Pillow lo descarta por defecto en JPG y WebP y solo lo mantiene en PNG. Subir la calidad no arregla nada: a calidad 100 el JPG de Pillow sigue sin perfil.
Un perfil ICC es un bloque de datos dentro del archivo que dice en qué estándar hay que leer los números RGB. Los píxeles no se tocan; cambia la interpretación. Por eso la imagen se ve lavada y no borrosa. Cuando falta el perfil, el software asume sRGB.
La tabla, celda a celda
El origen era una foto CC0 de Wikimedia Commons hecha con un iPhone 6 en el aeropuerto de Madrid, redimensionada a 2048×1536. Como el iPhone 6 no captura P3 (eso llegó con el iPhone 7), la versión Display P3 se generó con ImageCms de Pillow, incrustando el perfil en un JPEG de calidad 92.
Con esa entrada y los ajustes por defecto: Pillow tira el perfil en JPG, lo mantiene en PNG y lo tira en WebP, y también lo pierde al redimensionar o generar miniaturas y guardar en JPG. ffmpeg lo conserva en JPG y PNG y lo pierde en WebP. sips mantiene JPG y PNG, incluso bajando la calidad a 60, y no generó archivo WebP en esa máquina, así que esa casilla queda sin probar.
En Pillow hay arreglo: si se le pasa el icc_profile de la imagen original al save, el perfil sobrevive tanto en JPG como en WebP. En ffmpeg no hay bandera verificada para llevarlo a WebP, y es mejor dejar la casilla honesta que inventarse un flag. La calidad decide cuánto detalle tira el codificador; el perfil es otro bloque del archivo y o se escribe o no se escribe.
Cuánto color se pierde
Renderizando ambas versiones como sRGB y midiendo ΔE76 en CIELAB, el P3 sin perfil daba un ΔE medio de 1,83 y un percentil 95 de 3,9, con solo el 1,7% de los píxeles por encima de ΔE 5. La croma media caía un 16,6%, y el 5% más saturado perdía un 15,3% de croma a un ΔE de 5,4. Una versión Adobe RGB de la misma foto salía peor: croma media un 20,1% abajo y un 7,4% de píxeles por encima de ΔE 5. Grises y blancos apenas se movían; el daño se concentraba en la cola roja y el cielo azul. Los colores de esta foto caben dentro de sRGB, así que no hay números para imágenes de gama ancha reales.
Para revisar un archivo en macOS, sips -g profile archivo imprime el nombre del perfil. Hay una trampa con JPG: un archivo sin perfil alguno reporta sRGB IEC61966-2.1, igual que uno con un sRGB incrustado de verdad. Toca mirar entrada y salida en paralelo y ver que el origen dice Display P3 y la salida dice sRGB. Otras plataformas tienen visores de metadatos equivalentes.
Antes de fiarse de un paso de compresión nuevo, lo sensato es pasar una imagen P3 por él y comprobar todos los formatos de salida uno a uno. Solo después tiene sentido lanzar el lote entero.

