为什么使用JavaIO加载这个jpg会产生CMMException?

Pau*_*lor 8 java jpeg image-processing javax.imageio

带有此文件的ImageIO.read(imagePath)给出了一个CMMException,为什么Java无法处理这个看似有效的文件http://www.jthink.net/jaikoz/scratch/front.jpg

java.awt.color.CMMException: Invalid image format
    at sun.awt.color.CMM.checkStatus(Unknown Source)
    at sun.awt.color.ICC_Transform.<init>(Unknown Source)
    at java.awt.image.ColorConvertOp.filter(Unknown Source)
    at com.sun.imageio.plugins.jpeg.JPEGImageReader.acceptPixels(Unknown Source)
    at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImage(Native Method)
    at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(Unknown Source)
    at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(Unknown Source)
    at javax.imageio.ImageIO.read(Unknown Source)
    at javax.imageio.ImageIO.read(Unknown Source)
Run Code Online (Sandbox Code Playgroud)

Fav*_*ius 15

我想我已经掌握了你的问题.我查看了您链接的图片(http://www.jthink.net/jaikoz/scratch/front.jpg).它由于Exif和JFIF标准.

当你做这样的事情ImageIO.read('some file')时调用默认的sun jpeg实现com.sun.imageio.plugins.jpeg.JPEGImageReader.以前哪些问题加载JFIF文件BUG 6488904(检查评论结束).

根据规范,Exif和JFIF都要求他们各自的应用程序标记段必须是SOI(APP1和APP0)之后的第一个,因此实际上每个规范都不可能使JPEG文件符合这两个标准.

虽然据报道很久以前回来了

解决方法是使用JAI库(https://jai.dev.java.net/binary-builds.html#Release_builds).我使用的是Java(没有原生加速)版本.

SeekableStream seekableStream =  new FileSeekableStream(new File("front.jpg"));
ParameterBlock pb = new ParameterBlock();
pb.add(seekableStream);

BufferedImage image = JAI.create("jpeg", pb).getAsBufferedImage();
Run Code Online (Sandbox Code Playgroud)

希望这会有所帮助.