有没有100%的Java替代方案来读取JPEG文件?

我们正在使用Java2D来调整上传到我们网站的照片的大小,但是我们遇到了一个问题(一个看似古老的问题,参见:http://forums.sun.com/thread.jspa?threadID=5425569) - 当我们尝试使用包含其二进制数据的输入流时,一些特定的JPEG会提出一个问题:CMMExceptionImageIO.read()

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

(截取了堆栈跟踪的其余部分,这是我们的调用,servlet代码等)ImageIO.read()

我们将其缩小到在特定相机上拍摄的照片,我选择了触发此错误的照片:http://img214.imageshack.us/img214/5121/estacaosp.jpg。我们注意到这只发生在Sun的JVM上(在Linux和Mac上,刚刚在1.6.0_20上测试了它) - 带有OpenJDK的测试机器可以顺利地读取相同的照片,可能是由于JPEG阅读器的不同实现。

不幸的是,我们无法在生产环境中切换JVM,也无法使用依赖于本机的解决方案,例如ImageMagick( http://www.imagemagick.org/ )。

考虑到这一点,我的问题是:是否存在可以处理照片(例如链接的照片)的ImageIOs JPEG阅读器的替代品?如果没有,我们是否可以使用另一种100%纯Java照片大小调整解决方案?

谢谢!


答案 1

一个可能对您有用的库可能是Java高级映像库(JAI))

使用此库可能比使用 ImageIO 复杂得多,但在我刚刚运行的快速测试中,它确实打开并显示了您链接的问题图像文件。

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

运行此代码后,图像似乎加载正常。然后使用参数块将其大小调整50%

最后,如果您想保存文件,只需调用:

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

我希望这对你有所帮助。祝你好运。


答案 2

旧帖子,但供将来参考:

受到这个问题和在这里找到的链接的启发,我为ImageIO编写了一个JPEGImageReader插件,该插件支持具有这些“坏”ICC颜色配置文件的JPEG图像(“问题”是ICC配置文件中的渲染意图与Java的ColorConvertOp不兼容)。它是普通的Java,不需要JAI。

源代码和链接的二进制版本可从 GitHub 上的 TwelveMonkeys 项目免费获得。


推荐