java jpeg java-2d javax.imageio resize-image

resize image java



¿Existe una alternativa 100% Java a ImageIO para leer archivos JPEG? (3)

Estamos utilizando Java2D para cambiar el tamaño de las fotos subidas a nuestro sitio web, pero nos encontramos con un problema (aparentemente viejo, consulte: http://forums.sun.com/thread.jspa?threadID=5425569 ) - algunos archivos JPEG en particular CMMException una CMMException cuando intentamos ImageIO.read() un InputStream que contiene sus datos binarios:

java.awt.color.CMMException: Invalid image format at sun.awt.color.CMM.checkStatus(CMM.java:131) at sun.awt.color.ICC_Transform.<init>(ICC_Transform.java:89) at java.awt.image.ColorConvertOp.filter(ColorConvertOp.java:516) at com.sun.imageio.plugins.jpeg.JPEGImageReader.acceptPixels(JPEGImageReader.java:1114) at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImage(Native Method) at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:1082) at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:897) at javax.imageio.ImageIO.read(ImageIO.java:1422) at javax.imageio.ImageIO.read(ImageIO.java:1326) ...

(cortó el resto del seguimiento de la pila, que es nuestra llamada ImageIO.read() , el código de servlet y ImageIO.read() )

Lo reducimos a fotos tomadas en cámaras específicas, y seleccioné una foto que provoca este error: http://img214.imageshack.us/img214/5121/estacaosp.jpg . Notamos que esto solo sucede con la JVM de Sun (en Linux y Mac, solo probada en 1.6.0_20) - una máquina de prueba con OpenJDK lee las mismas fotos sin problemas, posiblemente debido a una implementación diferente del lector JPEG.

Desafortunadamente, no podemos cambiar JVM en producción, ni utilizar soluciones dependientes de los nativos, como ImageMagick ( http://www.imagemagick.org/ ).

Teniendo en cuenta eso, mi pregunta es: ¿Existe un reemplazo para el lector JPEG de ImageIO que pueda manejar fotos como la enlazada? Si no es así, ¿hay otra solución de cambio de tamaño de foto de Java 100% pura que podamos usar?

¡Gracias!


Antigua publicación, pero para futura referencia:

Inspirado por esta pregunta y los enlaces que se encuentran aquí, he escrito un complemento JPEGImageReader para ImageIO que admite imágenes JPEG con este tipo de perfiles de color ICC "malos" (el "problema" es la intención de representación en el perfil ICC es incompatible con ColorConvertOp de Java ). Es Java simple y no requiere JAI.

El código fuente y las compilaciones binarias vinculadas están disponibles gratuitamente en el proyecto TwelveMonkeys en GitHub.


Me enfrenté al mismo problema. Estaba reacio a usar JAI ya que está desactualizado, pero parece que es la solución más corta.

Este código convierte un InputStream en un BufferedImage, usando ImageIO de Sun (rápido) o en los pocos casos donde ocurre este problema, usando JAI:

public static BufferedImage read(InputStream is) throws IOException { try { // We try it with ImageIO return ImageIO.read(ImageIO.createImageInputStream(is)); } catch (CMMException ex) { // If we failed... // We reset the inputStream (start from the beginning) is.reset(); // And use JAI return JAI.create("stream", SeekableStream.wrapInputStream(is, true)).getAsBufferedImage(); } }


Una posible biblioteca útil para usted podría ser la Biblioteca de Imágenes Avanzadas de Java ( JAI )

El uso de esta biblioteca puede ser un poco más complicado que usar ImageIO, pero en una prueba rápida que acabo de ejecutar, se abrió y mostró el archivo de imagen de problema que vinculaste.

public static void main(String[] args) { RenderedImage image = JAI.create("fileload", "estacaosp.jpg"); float scale=(float) 0.5; ParameterBlock pb = new ParameterBlock(); pb.addSource(image); pb.add(scale); pb.add(scale); pb.add(1.0F); pb.add(1.0F); pb.add(new InterpolationNearest() );// ;InterpolationBilinear()); image = JAI.create("scale", pb); // Create an instance of DisplayJAI. DisplayJAI srcdj = new DisplayJAI(image); JScrollPane srcScrollPaneImage = new JScrollPane(srcdj); // Use a label to display the image JFrame frame = new JFrame(); frame.getContentPane().add(srcScrollPaneImage, BorderLayout.CENTER); frame.pack(); frame.setVisible(true); }

Después de ejecutar este código, la imagen parece cargar bien. Luego se redimensiona en un 50% usando el ParamaterBlock

Y finalmente, si desea guardar el archivo, simplemente puede llamar al:

String filename2 = new String ("tofile.jpg"); String format = new String ("JPEG"); RenderedOp op = JAI.create ("filestore", image, filename2, format);

Espero que esto te ayude. La mejor de las suertes.