通过ICC配置文件为JPEG执行颜色空间转换
JPEG格式的颜色管理
本文讨论了使用ICC配置文件在处理JPEG格式时执行颜色空间管理的方法,使用Aspose.PSD API。JPEG内部颜色空间是YCbCr,但该格式也可以容纳灰度、RGB、CMYK和YCCK颜色空间以存储图像的元数据。Aspose.PSD API主要在RGB空间中运行,因此API必须执行颜色空间的转换,以正确处理JPEG文件。可以使用数学转换进行灰度到RGB和YCbCr到RGB的转换,但CMYK和YCCK空间不能轻松地转换为RGB空间。
Aspose.PSD API必须执行直接的RGB到CMYK颜色转换,以处理具有CMYK颜色空间的JPEG图像。另一方面,具有YCCK颜色空间的图像需要进行RGB到CMYK到YCCK的颜色转换,其中CMYK到YCCK转换使用ITU-R BT.601转换应用于前三个通道,保持k通道不变。简而言之,Aspose.PSD API必须执行RGB和CMYK颜色空间之间的互相转换,以处理CMYK和YCCK图像,这些转换是通过ICC配置文件执行的,这些配置文件基本上是描述颜色属性并帮助颜色转换的查找表。
ICC配置文件
ICC转换机制使用“配置文件”,将源颜色空间映射到设备无关的CIELAB或CIEXYZ颜色空间。Aspose.PSD可以在需要时将数据转换为这两种颜色空间,并使用附加配置文件。因此,对于ICC转换,用户需要提供两个配置文件 - 一个RGB配置文件,以获得内部CIE颜色空间,一个CMYK配置文件,以获得CMYK颜色特性。为实现CMYK到RGB转换,需要交换配置文件,即使用CMYK配置文件作为源配置文件,RGB配置文件作为目标配置文件。
通过ICC配置文件为JPEG执行颜色转换
Aspose.PSD API隐藏了细节,通过JpegOptions类提供了一个简单易用的机制来指定ICC配置文件。此外,Aspose.PSD使用SWOP CMYK和sRGB的样本配置文件嵌入到其核心中,因此在大多数常见用法场景中,用户不需要寻找任何特定的配置文件。这种纠正的缺点是,这样的颜色空间转换是不可逆的,因为我们不能期望在RGB到CMYK到RGB转换后获得相同的颜色,这是由于不兼容的颜色空间和不同的颜色配置文件。以下代码片段演示了使用Aspose.PSD for Java API指定YCCK JPEG图像的RGB和CMYK颜色配置文件。在下面的示例中,RGB和CMYK颜色配置文件被更改,并且图像被保存到YCCK颜色空间。请注意,这些RgbColorProfile和CmykColorProfile属性将用于更改YCCK颜色空间的像素数据,所有其他颜色空间都不会提取颜色配置文件以更新颜色数据。
String dataDir = Utils.getDataDir(ColorConversionUsingICCProfiles.class) + "Conversion/"; | |
// Create a new JpegImage. | |
try (PsdImage image = new PsdImage(500, 500)) { | |
// Fill image data. | |
int count = image.getWidth() * image.getHeight(); | |
int[] pixels = new int[count]; | |
int r = 0; | |
int g = 0; | |
int b = 0; | |
int channel = 0; | |
for (int i = 0; i < count; i++) { | |
if (channel % 3 == 0) { | |
r++; | |
if (r == 256) { | |
r = 0; | |
channel++; | |
} | |
} else if (channel % 3 == 1) { | |
g++; | |
if (g == 256) { | |
g = 0; | |
channel++; | |
} | |
} else { | |
b++; | |
if (b == 256) { | |
b = 0; | |
channel++; | |
} | |
} | |
pixels[i] = Color.fromArgb(r, g, b).toArgb(); | |
} | |
// Save the newly created pixels. | |
image.saveArgb32Pixels(image.getBounds(), pixels); | |
// Save the resultant image with default Icc profiles. | |
image.save(dataDir + "Default_profiles.jpg"); | |
// Update color profile. | |
File rgbFile = new File(dataDir + "eciRGB_v2.icc"); | |
FileInputStream rgbInputStream = new FileInputStream(rgbFile); | |
StreamSource rgbprofile = new StreamSource(rgbInputStream); | |
File cmykFile = new File(dataDir + "ISOcoated_v2_FullGamut4.icc"); | |
FileInputStream cmykInputStream = new FileInputStream(cmykFile); | |
StreamSource cmykprofile = new StreamSource(cmykInputStream); | |
image.setRgbColorProfile(rgbprofile); | |
image.setCmykColorProfile(cmykprofile); | |
// Save the resultant image with new YCCK profiles. You will notice differences in color values if compare the images. | |
JpegOptions options = new JpegOptions(); | |
options.setColorType(JpegCompressionColorMode.Ycck); | |
image.save(dataDir + "Ycck_profiles.jpg", options); | |
} |
如果没有设置配置文件,则Aspose.PSD for Java API将使用默认配置文件。下面的示例使用目标配置文件属性为大多数JpegImages更改目标颜色空间。
String dataDir = Utils.getDataDir(ColorConversionUsingDefaultProfiles.class) + "Conversion/"; | |
try (PsdImage image = new PsdImage(500, 500)) { | |
// Fill image data. | |
int count = image.getWidth() * image.getHeight(); | |
int[] pixels = new int[count]; | |
int r = 0; | |
int g = 0; | |
int b = 0; | |
int channel = 0; | |
for (int i = 0; i < count; i++) { | |
if (channel % 3 == 0) { | |
r++; | |
if (r == 256) { | |
r = 0; | |
channel++; | |
} | |
} else if (channel % 3 == 1) { | |
g++; | |
if (g == 256) { | |
g = 0; | |
channel++; | |
} | |
} else { | |
b++; | |
if (b == 256) { | |
b = 0; | |
channel++; | |
} | |
} | |
pixels[i] = Color.fromArgb(r, g, b).toArgb(); | |
} | |
// Save the newly created pixels. | |
image.saveArgb32Pixels(image.getBounds(), pixels); | |
// Save the newly created image. | |
image.save(dataDir + "Default.jpg"); | |
// Update color profile. | |
File rgbFile = new File(dataDir + "eciRGB_v2.icc"); | |
FileInputStream rgbInputStream = new FileInputStream(rgbFile); | |
StreamSource rgbprofile = new StreamSource(rgbInputStream); | |
File cmykFile = new File(dataDir + "ISOcoated_v2_FullGamut4.icc"); | |
FileInputStream cmykInputStream = new FileInputStream(cmykFile); | |
StreamSource cmykprofile = new StreamSource(cmykInputStream); | |
image.setRgbColorProfile(rgbprofile); | |
image.setRgbColorProfile(cmykprofile); | |
// Save the resultant image with new YCCK profiles. You will notice differences in color values if compare the images. | |
JpegOptions options = new JpegOptions(); | |
options.setColorType(JpegCompressionColorMode.Cmyk); | |
image.save(dataDir + "Cmyk_Default_profiles.jpg", options); | |
} |