[我们正在使用Java2D来调整上传到我们网站的照片的大小,但是我们遇到了一个问题(一个看似古老的文件,请参阅:http://forums.sun.com/thread.jspa?threadID=5425569)-尝试CMMException
时,一些特定的JPEG会产生一个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/。]
[考虑到我的问题是:是否存在替代ImageIOs JPEG阅读器的替代品,该阅读器可以处理诸如链接的照片之类的照片?如果没有,还有另外一种我们可以使用的100%纯Java照片大小调整解决方案吗?
谢谢!
一个可能对您有用的库可能是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);
}
运行此代码后,图像似乎可以正常加载。然后使用ParamaterBlock将其调整大小为50%
最后,如果您想保存文件,则可以致电:
String filename2 = new String ("tofile.jpg");
String format = new String ("JPEG");
RenderedOp op = JAI.create ("filestore", image, filename2, format);
我希望这对您有所帮助。祝你好运。
[旧帖子,但供将来参考:
受此问题和此处链接的启发,我为ImageIO编写了一个JPEGImageReader插件,该插件支持具有此类“不良” ICC颜色配置文件(“问题”是ICC配置文件中的渲染意图与Java的ColorConvertOp)。它是纯Java,不需要JAI。
源代码和链接的二进制版本可从GitHub上的TwelveMonkeys project免费获得。
我遇到了同样的问题。我不愿意使用JAI,因为它已经过时了,但看起来这是最短的解决方案。
此代码使用sun的ImageIO(快速)将输入流转换为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();
}
}