我有多个图像,其中嵌入了自定义配置文件,并且希望将图像转换为 sRGB,以便将其提供给浏览器。我见过如下代码:
BufferedImage image = ImageIO.read(fileIn);
ColorSpace ics = ColorSpace.getInstance(ColorSpace.CS_sRGB);
ColorConvertOp cco = new ColorConvertOp(ics, null);
BufferedImage result = cco.filter(image, null);
ImageIO.write(result, "PNG", fileOut);
其中 fileIn
和 fileOut
是分别表示输入文件和输出文件的 File 对象。这在一定程度上是有效的。问题是生成的图像比原始图像更亮。如果我要在 Photoshop 中转换色彩空间,颜色看起来会是一样的。事实上,如果我用 Photoshop 提取两张图像并拍摄屏幕截图并对颜色进行采样,它们是相同的。 Photoshop 正在做什么而上面的代码没有做什么?我可以采取什么措施来纠正这个问题?
要转换的图像有多种类型,包括 JPEG、PNG 和 TIFF。我尝试过使用 TwelveMonkeys读取 JPEG 和 TIFF 图像,我仍然得到相同的效果,但图像太亮。当应用于一开始就没有嵌入配置文件的图像时,转换过程似乎最糟糕。
编辑:
我添加了一些示例图像来帮助解释问题。
- 该图像是嵌入了颜色配置文件的图像。在某些浏览器上查看时,此浏览器与下一个浏览器之间不会有明显差异,但在 Mac OSX 和 Windows 上的 Chrome 中查看,它目前看起来比应有的更暗。这就是我的问题的根源。我需要将图像转换为可以在 Chrome 中正确显示的图像。
- 这是使用 ImageMagick 转换为 Adobe RGB 1998 颜色配置文件的图像,Chrome 似乎能够正确显示。
- 这是我使用上面的代码转换的图像,它看起来比应有的更亮。
(请注意,上面的图像位于 imgur 上,因此要使它们更大,只需从文件名末尾、文件扩展名之前删除“t”即可。)
最佳答案
这是我最初的解决方案,它有效,但我不喜欢必须使用 ImageMagick。我根据我最终坚持的解决方案创建了另一个答案。
我屈服了,最终使用了 im4java ,它是 image magick 命令行工具的包装。当我使用以下代码获取 BufferedImage 时,效果非常好。
IMOperation op = new IMOperation();
op.addImage(fileIn.getAbsolutePath());
op.profile(colorFileIn.getAbsolutePath());
op.addImage("png:-");
ConvertCmd cmd = new ConvertCmd();
Stream2BufferedImage s2b = new Stream2BufferedImage();
cmd.setOutputConsumer(s2b);
cmd.run(op);
BufferedImage image = s2b.getImage();
我还可以在需要时使用该库应用 CMYK 配置文件进行打印。如果 ColorConvertOp 正确地进行了转换,那就太好了,但至少现在,这是我的解决方案。为了与我的问题达到同等效果,在问题中实现相同效果的 im4java 代码是:
ConvertCmd cmd = new ConvertCmd();
IMOperation op = new IMOperation();
op.addImage(fileIn.getAbsolutePath());
op.profile(colorFileIn.getAbsolutePath());
op.addImage(fileOut.getAbsolutePath());
cmd.run(op);
其中 colorFileIn.getAbosolutePath()
是 sRGB 颜色配置文件在计算机上的位置。由于 im4java 使用命令行,因此执行操作的方式并不直接,但对该库进行了详细解释 here 。我最初遇到图像魔法无法在我的 Mac 上运行的问题,如问题中所述。我使用brew安装了它,但结果在Mac上你必须像brew install imagemagick --with-little-cms
一样安装它。之后,图像魔法对我来说效果很好。
关于java - 在 Java 中,将图像转换为 sRGB 会使图像太亮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28593941/