读取JPEG:ImageIO.read()会弄乱色彩空间

时间:2011-09-19 16:29:16

标签: java jpeg javax.imageio

我正在尝试在Servlet中读取,重新缩放和保存图像。这是相关的代码:

BufferedImage image = ImageIO.read(file);

BufferedImage after = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
AffineTransform at = AffineTransform.getScaleInstance(factor, factor);
AffineTransformOp scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
after = scaleOp.filter(image, null);

ImageIO.write(after, "JPG", file));

原始文件是普通的RGB-Jpeg,但是当我打开并保存文件时,它会以CMYK-Jpeg的形式出现。即使我没有重新缩放图像,只是打开和关闭图像会导致问题。

当我打开PNG或GIF时,一切都很好。有人知道该怎么做吗?我希望ImageIO的read-Method能够保留原始的色彩空间。

如果有另一种方式来阅读jpeg的方式吗?

感谢您的任何建议!

3 个答案:

答案 0 :(得分:4)

您创建after,然后使用scaleOp.filter覆盖它。它是否正确?因此,即使您认为它是after图像,也可能不是RGB?如果您希望after为RGB,那么在进行转换之前,您可能需要在image上“绘制”after

答案 1 :(得分:1)

我遇到了同样的问题,并找到了这个页面。

我尝试了上面的建议,即创建一个具有正确类型的BufferedImage,并在过滤器调用中将其用作后映像而不是null;这确实解决了这个问题。

答案 2 :(得分:1)

ImageIO.read忽略所有嵌入的元数据,包括嵌入的颜色配置文件,它定义了RBG值如何映射到屏幕或打印机等物理设备。

您可以单独阅读元数据并将其传递给ImageIO.write,但将图像转换为(默认)sRGB颜色空间并忽略元数据会更容易。

如果您不介意丢失元数据,请替换

after = scaleOp.filter(image, null);

after = scaleOp.filter(image, after);

来自AffineTransformOp.filter的文档:

If the color models for the two images do not match, a color conversion into the destination color model is performed.