Конвертація простору кольорів для JPEG через ICC-профілі

Керування кольором для формату JPEG

У цій статті обговорюється використання ICC-профілів для виконання управління простором кольорів при роботі з форматом JPEG за допомогою API Aspose.PSD. Внутрішній колірний простір JPEG - YCbCr, однак у цьому форматі також можуть бути використані простори кольорів Grayscale, RGB, CMYK та YCCK для збереження метаданих зображення. API Aspose.PSD в основному працює в просторі RGB, тому API повинен виконувати конвертацію кольорових просторів в обидва напрямки для належної обробки файлів JPEG. Конвертацію кольорів від відтінків в сірий і віттінків YCbCr в RGB можна виконати за допомогою математичних перетворень, але простори CMYK та YCCK не можуть бути легко перетворені в простір RGB.

API Aspose.PSD повинен виконувати безпосереднє перетворення кольору RGB в CMYK для зображень формату JPEG з простором кольорів CMYK. З іншого боку, зображення з простором кольорів YCCK вимагають перетворення кольору RGB в CMYK в YCCK, де перетворення CMYK в YCCK використовує конвертацію ITU-R BT.601, яка застосовується до перших трьох каналів, залишаючи без змін k-канал. Іншими словами, API Aspose.PSD повинен виконувати взаємне перетворення кольорових просторів RGB та CMYK для обох типів зображень CMYK та YCCK, а такі перетворення виконуються за допомогою ICC-профілів, які по суті є таблицями пошуку, що описують властивості кольору та сприяють у кольорових перетвореннях.

ICC-профілі

Механізм конверсії ICC використовує “Профілі”, які відображають початковий простір кольору на пристрійно-незалежні простори кольорів CIELAB чи CIEXYZ. Aspose.PSD може перетворити дані в колірний простір за потреби, використовуючи ці обидва колірні простори разом з додатковими профілями. Тому для конверсії через ICC користувачу потрібно постачати два профілі - один RGB-профіль, щоб перейти до внутрішнього кольорового простору CIE, та один CMYK-профіль, щоб отримати характеристики кольору CMYK. Для досягнення конверсії CMYK в RGB потрібно поміняти профілі, тобто використовувати профіль CMYK як вихідний і профіль RGB як призначення.

Конвертація кольорів для JPEG через ICC-профілі

API Aspose.PSD приховує деталі, надаючи простий механізм для вказання ICC-профілів через клас JpegOptions. Більше того, Aspose.PSD використовує зразкові профілі SWOP CMYK та sRGB, вбудовані в його основу, тому у більшості випадків користувачу не потрібно шукати жодних конкретних профілів. Є недолік таких корекцій, а саме; такі конверсії кольорових просторів є незворотніми, оскільки ми не можемо очікувати того самого кольору після конверсії з RGB в CMYK в RGB через несумісні кольорові простори та різні кольорові профілі. Наведений нижче уривок коду демонструє використання Aspose.PSD для Java API для вказання профілів кольорів RGB та CMYK для зображення JPEG у просторі кольорів 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);
}

Якщо профілі не встановлені, то API Aspose.PSD для Java використовуватиме вмістові профілі за замовчуванням. У наведеному нижче прикладі використовуються властивості профілів призначення, які змінюють простір кольорів призначення для більшості 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);
}