Question

Nous utilisons Java2D pour redimensionner les photos mises en ligne sur notre site, mais nous nous heurtons à un problème (une apparence ancienne, cf .: http://forums.sun.com/thread.jspa?threadID=5425569 ) - quelques particuliers soulèvent un JPEGs CMMException quand nous essayons de ImageIO.read() un InputStream contenant leurs données binaires :

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)
    ...

(ciselée du reste de la trace de la pile, qui est notre appel ImageIO.read(), le code de servlet et autres)

réduit à des photos prises sur les caméras spécifiques, et je choisis une photo qui déclenche cette erreur: http://img214.imageshack.us/img214/5121/estacaosp.jpg . Nous avons remarqué que cela se produit uniquement avec machine virtuelle Java de Sun (sur Linux et Mac, juste testé sur 1.6.0_20) - une machine de test avec OpenJDK lit les mêmes photos sans accroc, peut-être en raison d'une mise en œuvre différente du lecteur JPEG

Malheureusement, nous ne pouvons pas changer JVMs dans la production, ni d'utiliser des solutions dépendantes natifs comme ImageMagick ( http: / /www.imagemagick.org/ ).

Considérant que, ma question est la suivante: Est-ce que pour remplacer le lecteur ImageIOs JPEG qui peut gérer des photos, comme un lien exist? Sinon, est-il une autre solution de redimensionnement photo Java pur à 100% que nous pouvons utiliser?

Merci!

Était-ce utile?

La solution

Une bibliothèque peut-être utile pour vous pourriez être le Java Advanced Imaging Library ( JAI)

L'utilisation de cette bibliothèque peut être un peu plus compliqué que d'utiliser ImageIO mais dans un test rapide, j'ai juste couru il l'a fait ouvrir et afficher le fichier image de problème que vous avez lié.

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);
    }

Après avoir exécuté ce code l'image semble charger bien. Il est ensuite redimensionné de 50% en utilisant le ParamaterBlock

Et enfin, si vous souhaitez enregistrer le fichier que vous pouvez simplement appeler:

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

J'espère que cela vous aide. Bonne chance.

Autres conseils

Ancien poste, mais pour référence future:

Inspirés par cette question et des liens trouvés ici, j'ai écrit un plugin JPEGImageReader pour ImageIO qui prend en charge les images JPEG avec ce genre de profils de couleur ICC « mauvais » (la « question » est l'intention de rendu dans le profil ICC est incompatible avec ColorConvertOp Java). Il est clair Java et ne nécessite pas l'IMA.

Le code source et binaire lié construit sont disponibles gratuitement sur le projet sur GitHub.

Je fait face à la même question. Je suis réticent à utiliser comme il est JAI obsolète mais il semble que c'est la plus courte solution.

Ce code convertit un InputStream à un BufferedImage, en utilisant ImageIO (rapide) ou dans les rares cas de soleil où ce problème se produit, en utilisant 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();
    }
}
scroll top