【问题标题】:Is there a 100% Java alternative to ImageIO for reading JPEG files?是否有 100% Java 替代 ImageIO 来读取 JPEG 文件?
【发布时间】:2019-12-01 15:34:08
【问题描述】:

我们正在使用 Java2D 调整上传到我们网站的照片的大小,但我们遇到了一个问题(一个看似旧的问题,参见:http://forums.sun.com/thread.jspa?threadID=5425569) - 当我们尝试使用 @987654327 时,一些特定的 JPEG 会引发 CMMException @ 一个包含其二进制数据的 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/) 等依赖于本机的解决方案。

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

谢谢!

【问题讨论】:

  • 顺便说一下,我知道 ImageIO 不处理 CMYK 图像(根据stackoverflow.com/questions/2408613/…)。但是示例之一是 RGB(就 Mac 预览而言,如果有人能确认这一点会很高兴)
  • 我在这里打开了一个关于 Oracle/Sun 错误数据库的错误:bugs.sun.com/bugdatabase/view_bug.do?bug_id=7064516 如果您仍然对修复感兴趣,请投票!
  • 请注意,此错误在 2012 年被标记为“在 Java 8b56 中修复”。因此,另一种解决方案是更新到最新的 Java 8(或更高版本)。

标签: java jpeg java-2d javax.imageio resize-image


【解决方案1】:

Java Advanced Imaging Library (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);
    }

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

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

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

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

【讨论】:

  • 确实如此!必须检查它在“无头”设置上的效果如何,但我相信我们可以解决。谢谢!
  • 只是为了让您知道,我们的开发人员实施了这个解决方案,而且效果非常好。再次感谢您!
  • 死链接,请使用oracle.com/technetwork/java/current-142188.html 或现在的任何内容进行更新。
【解决方案2】:

旧帖,但供将来参考:

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

源代码和链接的二进制构建可从 GitHub 上的 TwelveMonkeys project 免费获得。

【讨论】:

    【解决方案3】:

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

    此代码使用 sun 的 ImageIO(快速)或在出现此问题的少数情况下使用 JAI 将 InputStream 转换为 BufferedImage:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-16
      • 2013-10-30
      • 1970-01-01
      • 1970-01-01
      • 2014-08-06
      • 1970-01-01
      相关资源
      最近更新 更多