Pregunta

Primero me gustaría explicar la situación/requisitos que llevan a la pregunta:

En nuestra aplicación web no podemos admitir imágenes CMYK (JPEG) ya que IE 8 y versiones inferiores no pueden mostrarlas.Por ello necesitamos detectar cuando alguien quiere subir dicha imagen y negarla.

Desafortunadamente, ImageIO de Java no lee esas imágenes o no me permite obtener el espacio de color detectado.Desde la depuración parece que JPEGImageReader internamente obtiene el código de espacio de color 11 (lo que significaría JCS_YCCK) pero no puedo acceder de forma segura a esa información.

Cuando le pregunto al lector sobre los tipos de imágenes, no obtengo nada para CMYK, por lo que podría suponer no image types = unsupported image.

Convertí la imagen CMYK de origen a RGB usando una herramienta de imágenes para probar si sería legible (intenté simular los pasos del administrador cuando apareció el mensaje "No se admite CMYK").Sin embargo, JPEGImageReader No leería esa imagen, ya que asume (¡comenta en la fuente!) Espacio de color RGB de 3 componentes, pero el encabezado de la imagen informa 4 componentes (tal vez RGBA o ARGB) y, por lo tanto, un IllegalArgumentException es aventado.

Por lo tanto, ImageIO no es una opción ya que no puedo obtener de manera confiable el espacio de color de una imagen y no puedo decirle al administrador por qué una imagen que de otro modo sería buena (puede ser mostrada por el navegador) no sería aceptada debido a algún problema interno. error.

Esto me llevó a probar JAI ImageIO cuyo CLibJPEGImageReader Hace un excelente trabajo y lee correctamente todas mis imágenes de prueba.

Sin embargo, dado que estamos implementando nuestra aplicación en un JBoss que también podría albergar otras aplicaciones, nos gustaría mantenerlas lo más aisladas posible.AFAIK, necesitaría instalar JAI ImageIO en JRE o hacer que las bibliotecas nativas estén disponibles para poder usarlas y, por lo tanto, otras aplicaciones también podrían tener acceso a ellas, lo que podría causar efectos secundarios (al menos tendríamos hacer muchas pruebas para asegurar que ese no sea el caso).

Esa es la explicación de la pregunta, y aquí viene de nuevo:¿Existe alguna alternativa Java pura a JAI ImageIO que detecte de manera confiable y posiblemente convierta imágenes CMYK?

Gracias de antemano,

tomás

¿Fue útil?

Solución

Encontré una solución que está bien para nuestras necesidades: Apache Commons Sanselan. Esta biblioteca lee los encabezados JPEG bastante rápido y preciso (al menos todas mis imágenes de prueba), así como una serie de otros formatos de imagen.

La desventaja es que no leerá los datos de la imagen JPEG, pero puedo hacerlo con las herramientas BASIC JRE.

Leer imágenes JPEG para conversión es bastante fácil (las que ImageIO se niega a leer también):

JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(new FileInputStream( new File(pFilename) ) );
BufferedImage sourceImg = decoder.decodeAsBufferedImage();

Entonces, si Sanselan me dice que la imagen es en realidad cmyk, obtengo el ráster de la imagen de origen y me convierto:

for( /*each pixel in the raster, which is represented as int[4]*/ )
{  
   double k = pixel[3] / 255.0;

   double r = (255.0 - pixel[0])*k;
   double g = (255.0 - pixel[1])*k;
   double b = (255.0 - pixel[2])*k;
}

Esto da resultados bastante buenos en las imágenes RGB que no son demasiado brillantes u oscuras. Sin embargo, no estoy seguro de por qué multiplicar con k evita el brillo. El JPEG en realidad está decodificado en el código nativo y la conversión CMYK-> RGB que obtuve es algo diferente, solo probé la multiplica para ver el resultado visual.

Si alguien pudiera arrojar algo de luz sobre esto, estaría agradecido.

Otros consejos

He publicado un Java puro solución para leer todo tipo de imágenes JPEG y convertirlas en RGB.

Se basa en los siguientes hechos:

  • Si bien ImageIO no puede leer las imágenes JPEG con CMYK como una imagen búfered, puede leer los datos de píxeles sin procesar (ráster).
  • Sanselan (o imágenes de Apache Commons como se llama ahora) se puede usar para leer los detalles de las imágenes CMYK.
  • Hay imágenes con valores de CMYK invertidos (un viejo error de Photoshop).
  • Hay imágenes con YCCK en lugar de CMYK (se puede convertir fácilmente).

En nuestra aplicación web no podemos admitir imágenes CMYK (JPEG) ya que IE 8 y abajo no pueden mostrarlas.Por lo tanto, necesitamos detectar cuándo alguien quiere cargar dicha imagen y negarla.

No estoy de acuerdo con tu "Por eso necesitamos detectar cuando alguien quiere subir una imagen así y desmentirla".Una política mucho más fácil de usar sería convertirlo a algo distinto a CMYK.

El resto de tu publicación es un poco confuso en ese sentido, dado que solicitas tanto detección como conversión, que son dos cosas diferentes.Una vez más, creo que convertir la imagen es mucho más fácil de usar.

Por cierto, no es necesario escribir en negrita:

¿Hay alguna alternativa de Java pura a Jai ​​Imageio que detecta de manera confiable y posiblemente convierte las imágenes CMYK?

Java puro, no lo sé, pero ImageMagick funciona bien para convertir imágenes CMYK a RGB.Vocación ImagenMagia en el lado del servidor desde Java realmente no es complicado.Solía ​​hacerlo manualmente llamando a un proceso externo pero hoy en día existen contenedores como JMagick y im4java.

Tenga cuidado con otra publicación ya que el Java 7 no permite usar la implementación de DirectEd Sun sin parámetros especiales como se indica en import com.sun.image.codec.jpeg.*.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top