是否有 100% Java 替代 ImageIO 来读取 JPEG 文件?

发布于 2024-09-04 23:33:22 字数 1645 浏览 8 评论 0原文

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

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

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

我们缩小了范围到在特定相机上拍摄的照片,我选择了触发此错误的照片: http:// /img214.imageshack.us/img214/5121/estacaosp.jpg。 我们注意到,这种情况只发生在 Sun 的 JVM 上(在 Linux 和 Mac 上,刚刚在 1.6.0_20 上进行了测试)——使用 OpenJDK 的测试机器可以顺利读取相同的照片,这可能是由于 JPEG 读取器的实现不同所致。

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

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

谢谢你!

We are using Java2D to resize photos uploaded to our website, but we run into an issue (a seemingly old one, cf.: http://forums.sun.com/thread.jspa?threadID=5425569) - a few particular JPEGs raise a CMMException when we try to ImageIO.read() an InputStream containing their binary data:

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

(snipped the remainder of the stack trace, which is our ImageIO.read() call, servlet code and such)

We narrowed it down to photos taken on specific cameras, and I selected a photo that triggers this error: http://img214.imageshack.us/img214/5121/estacaosp.jpg.
We noticed that this only happens with Sun's JVM (on Linux and Mac, just tested it on 1.6.0_20) - a test machine with OpenJDK reads the same photos without a hitch, possibly due to a different implementation of the JPEG reader.

Unfortunately, we are unable to switch JVMs in production, nor to use native-dependent solutions such as ImageMagick ( http://www.imagemagick.org/ ).

Considering that, my question is: Does a replacement for ImageIOs JPEG reader which can handle photos such as the linked one exist? If not, is there another 100% pure Java photo resizing solution which we can use?

Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

扛刀软妹 2024-09-11 23:33:22

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

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

最后,如果您想保存文件,您可以调用:

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

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

One possibly useful library for you could be the Java Advanced Imaging Library (JAI)

Using this library can be quite a bit more complicated than using ImageIO but in a quick test I just ran, it did open and display the problem image file you linked.

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

After running this code the image seems to load fine. It is then resized by 50% using the ParamaterBlock

And finally if you wish to save the file you can just call :

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

I hope this helps you out. Best of luck.

清眉祭 2024-09-11 23:33:22

旧帖子,但供将来参考:

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

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

Old post, but for future reference:

Inspired by this question and links found here, I've written a JPEGImageReader plugin for ImageIO that supports JPEG images with these kind of "bad" ICC color profiles (the "issue" is the rendering intent in the ICC profile is incompatible with Java's ColorConvertOp). It's plain Java and does not require JAI.

The source code and linked binary builds are freely available from the TwelveMonkeys project on GitHub.

默嘫て 2024-09-11 23:33:22

我遇到了同样的问题。我不愿意使用 JAI,因为它已经过时了,但看起来它是最短的解决方案。

此代码使用 sun 的 ImageIO(快速)将 InputStream 转换为 BufferedImage,或者在出现此问题的少数情况下使用 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();
    }
}

I faced the same issue. I was reluctant to use JAI as it is outdated but it looks like it's the shortest solution.

This code converts an InputStream to a BufferedImage, using sun's ImageIO (fast) or in the few cases where this problem occur, using 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();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文