Конвертація простору кольорів для 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); | |
} |