【发布时间】:2017-08-11 16:53:06
【问题描述】:
我需要将客户提供的 JPG 图像转换为 sRGB 格式 (sRGB IEC61966-2.1) 以使它们为网络做好准备。
我可以用ImageIO和BufferedImage成功,但是这个操作真的很慢:
val srgbSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB)
val colorConversionOperation = new ColorConvertOp(srgbSpace, null)
val converted = colorConversionOperation.filter(inputImage, null)
(已经尝试将RenderingHints 提供给ColorConvertOp - 它没有帮助)
据我了解,罪魁祸首是BufferedImage,我需要在Rasters 上工作以加快速度:
val iccProfile = ICC_Profile.getInstance(ColorSpace.CS_sRGB)
val iccColorSpace = new ICC_ColorSpace(iccProfile)
val sourceColorSpace = inputImage.getColorModel.getColorSpace
val colorConversionOperation = new ColorConvertOp(sourceColorSpace, iccColorSpace, null)
val converted = colorConversionOperation.filter(inputImage.getRaster, null)
这确实带来了巨大的性能提升,但我不知道如何保存Raster,以便最终图像包含适当的色彩空间和色彩配置文件信息。
目前我通过以下方式从Raster 创建BufferedImage:
val outImage = new BufferedImage(ColorModel.getRGBdefault, converted, false, null);
当我使用BufferedImage 时,最终的 JPG 保存为:
Color space: RGB
Color profile: sRGB IEC61966-2.1
在这种情况下是正确的。
当我使用Rasters 时,最终的 JPG 保存为:
Color space: RGB
这意味着我丢失了Color profile 信息。我认为这是因为我在将Raster 转换为BufferedImage 时使用ColorModel.getRGBdefault,但我不知道如何为sRGB IEC61966-2.1 获取ColorModel 的实例。
【问题讨论】:
-
ColorModel.getRGBdefault始终位于 sRGB 颜色空间中(如 API 文档中所述)。但我同意,奇怪的是输出 JPEG 不同...问题是,(假设您使用ImageIO和它的JPEGImageWriter来编写图像)ICC 颜色配置文件是 not如果颜色空间是 sRGB,则默认写入。出于某种原因,converted图像中的颜色空间与 sRGB 相同,但isCS_sRGB()方法返回false(不知道为什么),这就是它的编写原因。我认为您可以通过在元数据(IIOMetadata类)中传递来强制写入 ICC 配置文件。 -
@haraldK 您是否知道将 ICC 配置文件传递给 IIOmedatada 的任何示例是否可用?我正在查看 IIOMetadata/JPEGMetadata,但我不知道如何在那里传递 ICC 配置文件。我的类路径上有十二个猴子 ImageIO,如果这可以提供任何帮助的话。
标签: java image-processing awt bufferedimage javax.imageio