2011-08-24 11 views
21

Trabajando con imágenes en Java por primera vez y obtengo algunas excepciones bizarras que no están documentadas muy bien. Aquí está la línea de código que está fallando:Java ImageIO IIOException: tipo de imagen no compatible?

BufferedImage imgSelected = ImageIO.read(new File("/abs/url/to/file/image.jpg")); 

Esta línea está lanzando una IIOException con admite el tipo de imagen como el mensaje de excepción. Comprobé y volví a verificar que, de hecho, esta línea arroja la excepción, que el objeto File es válido, que la URL es válida y que el image.jpg es de hecho un JPG válido que se carga perfectamente en otros visores de imágenes.

¿Qué podría hacer para obtener más información sobre la naturaleza de esta excepción? ¿Es esta la forma tradicional de cargar imágenes en Java 7, o es un método antiguo/desaprobatorio? Simplemente no hay mucha información sobre estas excepciones de "tipo de imagen no admitida", y seguramente, ¡los archivos JPG compatibles con ImageIO!

¡Gracias por cualquier ayuda!

Respuesta

27

Intente verificar la codificación de JPEG. ImageIO no puede leer imágenes jpeg con codificación CMYK, por ejemplo. AFAIK, ImageIO no se ha actualizado durante años, por lo que le gustaría probar y utilizar la alternativa/extensión oficial: JAI ImageIO.

Desafortunadamente, JAI ImageIO necesita algunas bibliotecas nativas instaladas en el JRE, lo que puede ser no deseado. hacemos lo siguiente:

  • uso Apache Sanselan de detectar, si se trata de un archivo JPEG
  • desde Sanselan no puede leer y escribir JPEG, utilice el viejo y simple AWT JPEGCodec: JPEGCodec.createJPEGDecoder(...)
  • para convertir CMYK a RGB , nos ofrece entonces la trama de la lectura BufferedImage y convertir manualmente (que podría utilizar perfiles ICC, pero la conversión manual se ajusta a nuestras necesidades)

Aquí hay una pregunta mía que resultó del hecho XX en ImageIO no es compatible con todos los tipos de imágenes JPEG, y allí expuse un poco más de mis hallazgos de por qué recibe ese mensaje: Pure Java alternative to JAI ImageIO for detecting CMYK images

+0

El problema aquí es que las bibliotecas nativas de JAI ImageIO (al menos en Windows) solo admiten 32 bits. – Trejkaz

9

Desafortunadamente encontré una gran cantidad de archivos JPEG que violan estándares. ImageIO es particularmente quisquilloso y a menudo se niega a cargar imágenes, que a menudo se cargan y aparentemente se muestran correctamente por otro software con controles menos estrictos en el formato de archivo.

No es muy bonita, pero una solución es utilizar el decodificador JPEG interna de Oracle VM directa (com.sun.image.codec.jpeg.JPEGCodec), ya que parece tolerar más desviaciones de especificaciones como el envoltorio ImageIO:

BufferedImage img = 
    JPEGCodec.createJPEGDecoder(inputStream).decodeAsBufferedImage(); 

Esto por supuesto no es una solución ideal, ya que el uso de clases específicas de implementación va a atar a un proveedor específico VM y puede romper con las nuevas versiones de máquinas virtuales, pero si usted sólo utilizó el software en un entorno controlado, puede ser mejor que ninguna solución en absoluto.

+0

Esa es una gran sugerencia @jarnbjo. Gracias por tomarse el tiempo para responder a mi pregunta, definitivamente algo para pensar en el futuro. – IAmYourFaja

+0

Lo he probado en una imagen cmyk causando la excepción como en el tema y falló (versión java "1.8.0_60"): com.sun.image.codec.jpeg.ImageFormatException: No es un archivo JPEG: comienza con 0xce 0x08 \t at sun.awt.image.codec.JPEGImageDecoderImpl.readJPEGStream (Método nativo) ~ [?: 1.8.0_60] – yetanothercoder

Cuestiones relacionadas