2009-08-13 23 views
10

Cuando leo ciertos archivos JPG, los colores se aplanan. Aquí hay un ejemplo simple que lee un jpg y simplemente escribe la misma imagen en otro archivo.Por qué Java ImageIO aplana los colores JPEG

import java.awt.image.BufferedImage; 
import java.io.File; 
import javax.imageio.ImageIO; 

public class JPegReadTest { 
    public static void main(String[] args) { 
     if (args.length == 2) { 
      try { 
       BufferedImage src = ImageIO.read(new File(args[0])); 
       ImageIO.write(src, "jpg", new File(args[1])); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } else { 
      System.err.println("Usage: java JPegReadTest src dest"); 
     } 
    } 
} 

Si intenta esto con, por ejemplo http://www.flickr.com/photos/visualpanic/233508614/sizes/l/, los colores de la imagen de destino difieren del archivo de origen. ¿Porqué es eso? ¿Como arreglarlo?

También intenté guardar la imagen como png, pero los colores también son sosos (por lo que supongo que la información de color no se lee correctamente).

+0

Tiene que encontrar la manera de preservar el perfil de color? Estoy enfrentando el mismo problema –

Respuesta

10

Puede haber varias razones.

  1. Los datos de color JPEG a menudo se almacenan como YCrCb en lugar de RGB, aunque las conversiones deberían ser casi imperceptibles.
  2. JPEG a menudo tiene un perfil de color incrustado, pero muchas aplicaciones no lo entienden y simplemente lo ignoran (en cuyo caso, su archivo de salida puede perder el perfil de color).
  3. El valor de gamma podría reiniciarse o perderse después de que Java lo haya desorganizado.

No probé tu ejemplo ... ¿Podrías publicar los archivos antes y después? Sin realmente poder examinar el archivo de resultados, es difícil saber si esta información adicional está allí o no.

Edit: Sí, está claro que sus imágenes originales y convertidas tienen diferentes perfiles de color. Java eliminó el perfil de color del original y usó sRGB genérico en su lugar. Nos parecen iguales en Windows con Firefox y programas variados porque estos programas no usan el perfil de color cuando se renderiza. Sin embargo, en su Mac, Mac realmente admite estos perfiles de color (debate de referencia sobre Mac para gráficos, etc.) y por lo tanto, se procesan de manera diferente. No tengo una Mac a mano, pero sospecho que si abre los archivos en Photoshop en cualquier plataforma, verá la diferencia.

+0

Ok, aquí están los archivos de antes y después. http://terokinnunen.jalbum.net/Colortest/orig.jpg http://terokinnunen.jalbum.net/Colortest/converted-jpg.jpg también trató de guardar como png, todavía blanda http: // terokinnunen .jalbum.net/Colortest/converted-png.png – ketorin

+0

Interesante: para mí (Ubuntu 9.04, Firefox 3.5/Gimp) el aspecto original y el convertido se ven más o menos iguales (artefactos JPEG modulu). La única diferencia que puedo encontrar con GIMP es que el original especifica "sRGB IEC61966-2.1" como el espacio de color, mientras que el convertido tiene "sRGB incorporado". –

+0

¿Lo hacen? De hecho interesante. Para mí (Mac y Safari o Firefox) los colores son notablemente diferentes en los convertidos. También revisé con Windows y, para mi sorpresa, también se ven más o menos iguales, solo una pequeña diferencia. – ketorin

0

jpeg es un formato con pérdida. Cuando se lee, java lo almacena como un formato sin procesar muy parecido a un BMP. Luego se está escribiendo de nuevo causando la pérdida de datos. Además, no hay mucho control sobre la calidad, como cuando se usa algo como GIMP.

Quizás analice el uso de otras API como Image Magick para tener más control sobre la calidad.

+2

irrelevante. OP está señalando un problema significativo de perfil de color más allá de la mera recompresión. – erjiang

0

JPEG es un formato lossy.

Eso significa que si abre un archivo y lo guarda de nuevo perderá algo de información a menos que tome pasos muy específicos para no perder ninguno (en cuyo caso las posibles manipulaciones son muy restringidas).

Además, ImageIO.write() probablemente utiliza algunos ajustes de calidad predeterminados para guardar archivos JPEG, que pueden ser menores que los originales, lo que podría conducir a una pérdida adicional de calidad.

Intente guardar en un archivo PNG y verá que se verá igual que la fuente.

+0

Intenté guardar en png, pero también se ve de un color insulso, al igual que la imagen guardada en jpg. Tengo la corazonada de que los colores ni siquiera se leen correctamente. – ketorin

+0

En ese caso, el problema podría ser que algún perfil de color se almacena en la imagen que Java no lee/interpreta. –

2

¿Quizás su imagen de origen tiene un perfil de color asignado con una gama más amplia que sRGB (como Adobe RGB), y su ciclo de carga/guardado no preserva la información de espacio de color? Sin un perfil de color, el espectador asumirá sRGB, y la gama comprimida hará que todo parezca "bla".Si tiene exiftool,

exiftool -ProfileDescription filename.jpg 

es una forma rápida de verificar los perfiles de color en sus imágenes de origen y de salida.

+0

Sí, este podría ser el problema, el perfil de hecho falta en los archivos de salida. Este hilo parece prometedor: http://forums.java.net/jive/thread.jspa?threadID=60631&tstart=0, vamos a verlo a continuación. – ketorin

+0

Vaya, ese fue el hilo equivocado: http://forums.java.net/jive/message.jspa?messageID=205964 – ketorin

0

Aquí hay un enlace con el código fuente que se expande en la interfaz ImageIO - puede cambiar los parámetros de calidad y compresión cuando se escribe una imagen .... http://www.universalwebservices.net/web-programming-resources/java/adjust-jpeg-image-compression-quality-when-saving-images-in-java

+0

Esto es vago. ¿Lo has probado con la imagen de la pregunta? Básicamente le está diciendo a OP que * verifique los documentos * nuevamente. Y la respuesta aceptada sugiere que esta respuesta no resolverá los problemas de OP. – andr

Cuestiones relacionadas