В этом разделе
1. Управление цветом, основные понятия
Управление цветом в цифровых изображениях - это контролируемое преобразование цветов изображения для достижения идентичного отображения изображения на всех устройствах.
Поскольку разные устройства имеют разные характеристики и возможности, возникает потребность в некоторой открытой и согласованной модели управления цветом, поддерживаемой большинством устройств и программных систем. На данный момент наиболее признанной моделью является модель управления цветом, разработанная International Color Consortium (ICC).
Модель ICC, наряду с широко используемыми цветовыми пространствами (RGB, CMYK, оттенки серого и т. д.), представляет концепцию цветового пространства
PCS (Пространство подключения профиля)
, который может быть одним из двух цветовых пространств:
-
PCSXYZ
- цветовое пространство, независимое от устройства, на основе CIEXYZ, относительно цветности источника света CIE D50.
-
PCSLAB
- аппаратно-независимое цветовое пространство, основанное на CIELAB, относительно цветности источника света CIE D50.
Основным способом хранения информации о преобразовании цвета в модели ICC является цветовой профиль
ICC цветовой профиль
. ICC-профиль определяет цветовые преобразования, необходимые для преобразования цвета из определенного цветового пространства в PCS или наоборот. Таким образом, для переноса цветов одного устройства в цвета другого достаточно цветового профиля, который определяет перенос цвета из цветового пространства первого устройства в PCS (этот профиль называется "исходным профилем"), и цветового профиля, который определяет перевод PCS в цветовое пространство второго устройства (этот профиль называется "целевым профилем").
Общая схема перевода цветов из одного цветового пространства в другое выглядит так:
Например, схема преобразования цветов из пространства CMYK в RGB может выглядеть так:
2. Архитектура управления цветом VintaSoft Imaging .NET SDK
Vintasoft Imaging .NET SDK имеет встроенную систему управления цветом, которая позволяет:
- Использовать управление цветом при декодировании файлов изображений.
- Использовать управление цветом при отображении и печати изображений.
- Выполнить преобразование цвета изображений.
- Получить преобразования цвета из ICC-профилей v.2.0-4.3.
- Использовать ряд стандартных преобразований цвета и определить собственные преобразования цвета.
Ключевые классы, позволяющие использовать управление цветом:
2.1. Класс ColorTransform - преобразование одного цвета
Термины:
-
Формат цвета
- сочетание цветового пространства с порядком цветовых каналов.
-
Преобразование цвета
- преобразование, которое с определенной доступной точностью переводит набор числовых значений, определяющих цвет в исходном цветовом формате, в упорядоченный набор числовых значений, определяющих цвет в цветовом формате назначения.
ColorTransform - базовый класс для всех преобразований цвета. Класс обеспечивает возможность работы с цветами и цветовыми векторами, имеющими вещественное (двойное) или целочисленное (8 или 16-битное) представление цветового канала.
Экземпляр цветового преобразования может быть:
Каждое цветовое преобразование определяет формат входного и выходного цвета.
Формат цвета определяется с помощью класса
ColorSpaceFormat, который определяет цветовое пространство с помощью перечисления
ColorSpaceType и порядка цветовых каналов с помощью класса
ColorChannelsOrder.
Формат входного и выходного цвета определяется в конструкторе цветового преобразования и не может быть изменен позже. Входной формат цвета можно получить с помощью свойства
ColorTransform.SourceColorFormat, а выходной формат - с помощью свойства
ColorTransform.DestColorFormat.
Класс
ColorTransform имеет набор методов, определяющих алгоритм преобразования цвета для различных представлений входных и выходных значений цвета:
Эти методы принимают 2 параметра: первый параметр - массив, определяющий исходный цвет или вектор цвета; второй параметр - массив, в который будет записан преобразованный цвет или вектор цвета. Значения массивов определяют значения цветовых каналов в соответствии с заданным цветовым форматом. Значения цветовых каналов могут быть представлены следующим образом:
- действительные числовые значения - определяют цветовой канал в диапазоне от 0 до 1, где 0 - минимальное, а 1 - максимальное значение. Значения представлены как тип System.Double[].
- 8-битные целые значения - определяют цветовой канал в диапазоне от 0 до 255, где 0 - минимальное, а 255 - максимальное значение. Значения представлены как тип System.Byte[].
- 16-битные целые значения - определяют цветовой канал в диапазоне от 0 до 65536, где 0 - минимальное, а 65536 - максимальное значение. Значения представлены как тип System.Byte[]. Каждый канал определяется двумя байтами, последовательно следующими друг за другом, первый из которых - младший байт 16-битного целого числа, а второй - старший байт.
Из перечисленных методов класса
ColorTransform только метод
ColorTransform.TransformVector является абстрактным и должен быть определен в производных классах, остальные методы в базовой реализации используют метод
ColorTransform.TransformVector для выполнения преобразования, при необходимости целочисленные значения преобразуются в вещественные значения и наоборот. Однако любой из методов можно переопределить в производном классе для повышения производительности или реализации некоторых дополнительных алгоритмов преобразования.
Класс имеет абстрактное свойство
ColorTransform.IsThreadSafe, которое предоставляет возможность определить, является ли преобразование цвета потокобезопасным или нет.
2.2. Класс "ColorTransforms" - стандартные цветовые преобразования
Статический класс
ColorTransforms содержит предопределенные стандартные цветовые преобразования в виде статических экземпляров.
Доступны следующие стандартные преобразования цвета:
- RGB => PCSXYZ
- RGB => PCSXYZ, с ускоренной производительностью.
- PCSXYZ => RGB
- PCSXYZ => BGR
- PCSXYZ => BGR, с ускоренной производительностью.
- PCSLAB => PCSXYZ
- PCSXYZ => PCSLAB
- Gray => PCSXYZ
- PCSXYZ => Gray.
В качестве пространства RGB используется стандартное пространство sRGB.
Вот диаграмма, показывающая стандартные цветовые преобразования, доступные в статическом классе
ColorTransforms. Зеленые овалы обозначают пространства, независимые от устройства, синие прямоугольники - пространства, зависящие от устройства. Стрелки указывают доступные цветовые преобразования в указанных направлениях.
В следующем примере показано, как преобразовать цвет в формате RGB в цвет в формате XYZ, используя стандартное преобразование из sRGB в PCSXYZ:
/// <summary>
/// Returns a XYZ color converted from specified RGB color
/// using standard color transform.
/// </summary>
public static Vintasoft.Imaging.ImageColors.XyzColor TransformRgbToXyz(
Vintasoft.Imaging.ImageColors.Rgb24Color rgbColor)
{
// fill buffer of RGB color
byte[] sourceColor = new byte[3];
sourceColor[0] = rgbColor.Red;
sourceColor[1] = rgbColor.Green;
sourceColor[2] = rgbColor.Blue;
// create buffer for XYZ color
double[] destColor = new double[3];
// perform color transform from byte values to double values
Vintasoft.Imaging.ColorManagement.ColorTransforms.SRgbToPcsXyzD50.TransformFrom8bitVector(
sourceColor, 0, 1, destColor, 0);
// return XYZ color
return new Vintasoft.Imaging.ImageColors.XyzColor(destColor[0], destColor[1], destColor[2]);
}
''' <summary>
''' Returns a XYZ color converted from specified RGB color
''' using standard color transform.
''' </summary>
Public Shared Function TransformRgbToXyz(rgbColor As Vintasoft.Imaging.ImageColors.Rgb24Color) As Vintasoft.Imaging.ImageColors.XyzColor
' fill buffer of RGB color
Dim sourceColor As Byte() = New Byte(2) {}
sourceColor(0) = rgbColor.Red
sourceColor(1) = rgbColor.Green
sourceColor(2) = rgbColor.Blue
' create buffer for XYZ color
Dim destColor As Double() = New Double(2) {}
' perform color transform from byte values to double values
Vintasoft.Imaging.ColorManagement.ColorTransforms.SRgbToPcsXyzD50.TransformFrom8bitVector(sourceColor, 0, 1, destColor, 0)
' return XYZ color
Return New Vintasoft.Imaging.ImageColors.XyzColor(destColor(0), destColor(1), destColor(2))
End Function
2.3. Класс "CompositeColorTransform" - составное цветовое преобразование
Термины:
-
Составное цветовое преобразование
- цветовое преобразование, которое содержит последовательность цветовых преобразований.
CompositeColorTransform - это базовый класс для составных цветовых преобразований. SDK содержит две реализации составных преобразований -
SimpleCompositeColorTransform и
FastCompositeColorTransform.
SimpleCompositeColorTransform класс имеет следующую особенность: если все цветовые преобразования, включенные в экземпляр класса
SimpleCompositeColorTransform, являются потокобезопасными, то само преобразование является потокобезопасным.
FastCompositeColorTransform класс не является потокобезопасным, но имеет более высокую производительность, чем
SimpleCompositeColorTransform, поскольку он использует внутренние буферы памяти для промежуточных преобразований.
Экземпляры классов можно создавать с помощью статических методов
SimpleCompositeColorTransform.Create и
FastCompositeColorTransform.Create. Каждый метод принимает в качестве параметра массив объединенных преобразований.
При создании составных преобразований необходимо учитывать, что в цепочке преобразований каждая пара соседних цветовых преобразований должна быть совместима, т.е. выходной формат первого цветового преобразования должен быть равен входному формату второго цветового преобразования.
В следующем примере показано, как создать составное цветовое преобразование, состоящее из указанных цветовых преобразований:
/// <summary>
/// Creates composite color transform that converts color from BGR format to RGB format
/// and then converts to XYZ format using standard color transform.
/// </summary>
public static Vintasoft.Imaging.ColorManagement.ColorTransform CreateCompositeColorTransform()
{
// channels order for BGR format
Vintasoft.Imaging.ColorChannelsOrder bgrOrder =
new Vintasoft.Imaging.ColorChannelsOrder(new int[] { 2, 1, 0 });
// channels order for RGB format
Vintasoft.Imaging.ColorChannelsOrder rgbOrder =
new Vintasoft.Imaging.ColorChannelsOrder(new int[] { 0, 1, 2 });
// create the channels order conversion transform
Vintasoft.Imaging.ColorManagement.ColorTransform bgrToRgbTransform =
new Vintasoft.Imaging.ColorManagement.ChannelsOrderConverterTransform(
Vintasoft.Imaging.ColorSpaceType.sRGB, bgrOrder, rgbOrder);
// create the composite transform using channels order conversion transform and standard transform
return Vintasoft.Imaging.ColorManagement.SimpleCompositeColorTransform.Create(
bgrToRgbTransform, Vintasoft.Imaging.ColorManagement.ColorTransforms.SRgbToPcsXyzD50);
}
''' <summary>
''' Creates composite color transform that converts color from BGR format to RGB format
''' and then converts to XYZ format using standard color transform.
''' </summary>
Public Shared Function CreateCompositeColorTransform() As Vintasoft.Imaging.ColorManagement.ColorTransform
' channels order for BGR format
Dim bgrOrder As New Vintasoft.Imaging.ColorChannelsOrder(New Integer() {2, 1, 0})
' channels order for RGB format
Dim rgbOrder As New Vintasoft.Imaging.ColorChannelsOrder(New Integer() {0, 1, 2})
' create the channels order conversion transform
Dim bgrToRgbTransform As Vintasoft.Imaging.ColorManagement.ColorTransform = New Vintasoft.Imaging.ColorManagement.ChannelsOrderConverterTransform(Vintasoft.Imaging.ColorSpaceType.sRGB, bgrOrder, rgbOrder)
' create the composite transform using channels order conversion transform and standard transform
Return Vintasoft.Imaging.ColorManagement.SimpleCompositeColorTransform.Create(bgrToRgbTransform, Vintasoft.Imaging.ColorManagement.ColorTransforms.SRgbToPcsXyzD50)
End Function
2.4. Класс "ColorTransformSet" - набор цветовых преобразований.
Термины:
-
Прямое цветовое преобразование.
- одно цветовое преобразование, позволяющее преобразовывать цвета из заданного входного формата в указанный выходной формат.
ColorTransformSet предоставляет возможность работать с цветовыми преобразованиями, как с набором. Набор поддерживает следующие операции:
- добавить цветовое преобразование
- удалить цветовое преобразование
- получить цветовое преобразование
- получить цепочку цветовых преобразований, используя информацию о формате ввода и вывода необходимого цветового пространства.
ColorTransformSet обеспечивает уникальность своих элементов за счет сочетания входного и выходного формата цветового пространства.
Класс
ColorTransformSet позволяет получить цветовое преобразование, необходимое для преобразования цвета из исходного формата цвета в целевой формат цвета. Существует два способа получить цветовое преобразование из набора:
-
Получить прямое цветовоое преобразование с помощью метода ColorTransformSet.GetDirectColorTransform. Метод ищет цветовое преобразование с указанными входными и выходными форматами в цветовых преобразованиях набора. Метод возвращает
null
, если подходящее преобразование не найдено.
-
Получить цепочку преобразований с помощью метода ColorTransformSet.GetColorTransform. Первоначально метод ищет прямое цветовое преобразование и возвращает его, если оно найдено. Если прямое цветовое преобразование не найдено, метод сформирует все возможные цепочки цветовых преобразований из заданного входного формата в заданный выходной формат. Метод вернет цепочку преобразований минимальной длины как составное преобразование (SimpleCompositeColorTransform), если найдена хотя бы одна цепочка преобразований; метод вернет
null
, если ни одна (одна) цепочка не найдена.
2.5. Класс "IccProfile" - ICC-профиль
Термины:
-
ICC цветовой профиль
определяет одно или несколько цветовых преобразований из одного формата в другой, а также некоторую дополнительную информацию.
-
Цель рендеринга
определяет стиль отображения значений цвета из одного цветового пространства в другое, когда гамма исходного цветового пространства превышает гамму целевого цветового пространства. Способ рендеринга по умолчанию - RenderingIntent.Perceptual.
Класс
IccProfile предоставляет возможность получения следующих цветовых преобразований:
Оба метода позволяют указать порядок цветовых каналов при преобразовании цвета и/или способ рендеринга.
Следующие свойства класса
IccProfile предоставляют возможность получения дополнительной информации:
В следующем примере показано, как получить преобразование цветового пространства устройства в цветовое пространство PCS из профиля ICC:
/// <summary>
/// Returns a color transform, which transforms colors from the device to PCS color space,
/// from specified ICC profile.
/// </summary>
public static Vintasoft.Imaging.ColorManagement.ColorTransform GetDeviceToPcsTransform(string iccProfileFilename)
{
using (Vintasoft.Imaging.ColorManagement.Icc.IccProfile profile =
new Vintasoft.Imaging.ColorManagement.Icc.IccProfile(iccProfileFilename))
{
return profile.GetDeviceToPcsTransform();
}
}
''' <summary>
''' Returns a color transform, which transforms colors from the device to PCS color space,
''' from specified ICC profile.
''' </summary>
Public Shared Function GetDeviceToPcsTransform(iccProfileFilename As String) As Vintasoft.Imaging.ColorManagement.ColorTransform
Using profile As New Vintasoft.Imaging.ColorManagement.Icc.IccProfile(iccProfileFilename)
Return profile.GetDeviceToPcsTransform()
End Using
End Function
2.6. Класс "ColorManagementDecodeSettings"
Класс
ColorManagementDecodeSettings предназначен для упрощения управления цветом при декодировании изображений.
ColorManagementDecodeSettings.ColorSpaceTransforms содержит набор цветовых преобразований, которые используются для преобразования цветов изображения. По умолчанию свойство
ColorManagementDecodeSettings.ColorSpaceTransforms содержит следующие стандартные цветовые преобразования:
- sRGB => PCSXYZ
- CMYK => PCSXYZ
- Gray => PCSXYZ
- PCSXYZ => sRGB
- PCSXYZ => Gray
- PCSXYZ => PCSLab
- PCSLab => PCSXYZ
Если профили ICC должны быть использованы для преобразования цветов изображения, необходимые профили ICC можно указать с помощью следующих свойств:
Изменение значения свойств
ColorManagementDecodeSettings.InputCmykProfile,
ColorManagementDecodeSettings.InputRgbProfile,
ColorManagementDecodeSettings.InputGrayscaleProfile,
ColorManagementDecodeSettings.OutputRgbProfile или
ColorManagementDecodeSettings.OutputGrayscaleProfile приводит к изменению набора цветовых преобразований, определяемых свойством
ColorManagementDecodeSettings.ColorSpaceTransforms.
Методы
ColorManagementDecodeSettings.GetColorTransform,
ColorManagementDecodeSettings.GetColorTransformUsingEmbeddedProfile и
ColorManagementDecodeSettings.GetColorTransformUsingEmbeddedProfileMetadata позволяют получить цветовое преобразование, необходимое для преобразования цветов изображения.
Дополнительные параметры управления цветом можно задать с помощью следующих свойств:
В следующем примере показано, как получить настройки управления цветом:
/// <summary>
/// Returns a ColorManagementDecodeSettings object
/// with specified ICC profiles for CMYK and RGB color spaces.
/// </summary>
public static Vintasoft.Imaging.ColorManagement.ColorManagementDecodeSettings GetColorManagementDecodeSettings(
string cmykProfileFilename, string rgbProfileFilename)
{
// create new ColorManagementDecodeSettings object
Vintasoft.Imaging.ColorManagement.ColorManagementDecodeSettings settings =
new Vintasoft.Imaging.ColorManagement.ColorManagementDecodeSettings();
// use black point compensation
settings.UseBlackPointCompensation = true;
// set input CMYK profile
settings.InputCmykProfile = new Vintasoft.Imaging.ColorManagement.Icc.IccProfile(cmykProfileFilename);
Vintasoft.Imaging.ColorManagement.Icc.IccProfile rgbProfile =
new Vintasoft.Imaging.ColorManagement.Icc.IccProfile(rgbProfileFilename);
// set input RGB profile
settings.InputRgbProfile = rgbProfile;
// set output RGB profile
settings.OutputRgbProfile = rgbProfile;
return settings;
}
''' <summary>
''' Returns a ColorManagementDecodeSettings object
''' with specified ICC profiles for CMYK and RGB color spaces.
''' </summary>
Public Shared Function GetColorManagementDecodeSettings(cmykProfileFilename As String, rgbProfileFilename As String) As Vintasoft.Imaging.ColorManagement.ColorManagementDecodeSettings
' create new ColorManagementDecodeSettings object
Dim settings As New Vintasoft.Imaging.ColorManagement.ColorManagementDecodeSettings()
' use black point compensation
settings.UseBlackPointCompensation = True
' set input CMYK profile
settings.InputCmykProfile = New Vintasoft.Imaging.ColorManagement.Icc.IccProfile(cmykProfileFilename)
Dim rgbProfile As New Vintasoft.Imaging.ColorManagement.Icc.IccProfile(rgbProfileFilename)
' set input RGB profile
settings.InputRgbProfile = rgbProfile
' set output RGB profile
settings.OutputRgbProfile = rgbProfile
Return settings
End Function
2.7. Преобразование цветов изображения
Преобразование цвета объекта
VintasoftImage можно выполнить с помощью класса
ColorTransformCommand. Для этого необходимо с помощью свойства
ColorTransformCommand.ColorTransform задать соответствующее преобразование цвета и применить команду к изображению.
В следующем примере показано, как выполнить преобразование цвета изображения:
/// <summary>
/// Applies a color transform command to specified VintasoftImage
/// using specified output RGB profile.
/// </summary>
public static void ApplyColorTransformCommand(
Vintasoft.Imaging.VintasoftImage image,
Vintasoft.Imaging.ColorManagement.Icc.IccProfile outputRgbProfile)
{
// create new color management decoding settings
Vintasoft.Imaging.ColorManagement.ColorManagementDecodeSettings colorManagement =
new Vintasoft.Imaging.ColorManagement.ColorManagementDecodeSettings();
// set output RGB profile
colorManagement.OutputRgbProfile = outputRgbProfile;
// get color transform
Vintasoft.Imaging.ColorManagement.ColorTransform colorTransform =
colorManagement.GetColorTransform(
Vintasoft.Imaging.ColorSpaceFormats.Bgr,
Vintasoft.Imaging.ColorSpaceFormats.Bgr
);
// create a color transform command
Vintasoft.Imaging.ImageProcessing.Color.ColorTransformCommand colorTransformCommand =
new Vintasoft.Imaging.ImageProcessing.Color.ColorTransformCommand();
// set color transform
colorTransformCommand.ColorTransform = colorTransform;
// apply color transform command
colorTransformCommand.ExecuteInPlace(image);
}
''' <summary>
''' Applies a color transform command to specified VintasoftImage
''' using specified output RGB profile.
''' </summary>
Public Shared Sub ApplyColorTransformCommand(image As Vintasoft.Imaging.VintasoftImage, outputRgbProfile As Vintasoft.Imaging.ColorManagement.Icc.IccProfile)
' create new color management decoding settings
Dim colorManagement As New Vintasoft.Imaging.ColorManagement.ColorManagementDecodeSettings()
' set output RGB profile
colorManagement.OutputRgbProfile = outputRgbProfile
' get color transform
Dim colorTransform As Vintasoft.Imaging.ColorManagement.ColorTransform = colorManagement.GetColorTransform(Vintasoft.Imaging.ColorSpaceFormats.Bgr, Vintasoft.Imaging.ColorSpaceFormats.Bgr)
' create a color transform command
Dim colorTransformCommand As New Vintasoft.Imaging.ImageProcessing.Color.ColorTransformCommand()
' set color transform
colorTransformCommand.ColorTransform = colorTransform
' apply color transform command
colorTransformCommand.ExecuteInPlace(image)
End Sub
2.8. Включение управление цветом при декодировании изображения
Свойство
VintasoftImage.DecodingSettings определяет настройки декодирования изображения. Свойство
DecodingSettings.ColorManagement определяет настройки управления цветом изображения.
Важно:
Управление цветом невозможно применить к изображению на основе растрового объекта (свойству
VintasoftImage.HasBitmapData присвоено значение
True
).
Следующий пример демонстрирует, как включить управление цветом при получении копии объекта
VintasoftImage:
/// <summary>
/// Returns a copy of specified RGB VintasoftImage with enabled color management
/// using specified input and output profiles.
/// </summary>
public static Vintasoft.Imaging.VintasoftImage GetImageCopy(
Vintasoft.Imaging.VintasoftImage image,
Vintasoft.Imaging.ColorManagement.Icc.IccProfile inputCmykProfile,
Vintasoft.Imaging.ColorManagement.Icc.IccProfile inputRgbProfile,
Vintasoft.Imaging.ColorManagement.Icc.IccProfile outputRgbProfile)
{
// create new color management decoding settings
Vintasoft.Imaging.ColorManagement.ColorManagementDecodeSettings colorManagement =
new Vintasoft.Imaging.ColorManagement.ColorManagementDecodeSettings();
// set input CMYK profile
colorManagement.InputCmykProfile = inputCmykProfile;
// set input RGB profile
colorManagement.InputRgbProfile = inputRgbProfile;
// set output RGB profile
colorManagement.OutputRgbProfile = outputRgbProfile;
// create decoding settings
if (image.DecodingSettings == null)
image.DecodingSettings = new Vintasoft.Imaging.Codecs.Decoders.DecodingSettings();
// set color management settings
image.DecodingSettings.ColorManagement = colorManagement;
// copy image with specified color management
return (Vintasoft.Imaging.VintasoftImage)image.Clone();
}
''' <summary>
''' Returns a copy of specified RGB VintasoftImage with enabled color management
''' using specified input and output profiles.
''' </summary>
Public Shared Function GetImageCopy(image As Vintasoft.Imaging.VintasoftImage, inputCmykProfile As Vintasoft.Imaging.ColorManagement.Icc.IccProfile, inputRgbProfile As Vintasoft.Imaging.ColorManagement.Icc.IccProfile, outputRgbProfile As Vintasoft.Imaging.ColorManagement.Icc.IccProfile) As Vintasoft.Imaging.VintasoftImage
' create new color management decoding settings
Dim colorManagement As New Vintasoft.Imaging.ColorManagement.ColorManagementDecodeSettings()
' set input CMYK profile
colorManagement.InputCmykProfile = inputCmykProfile
' set input RGB profile
colorManagement.InputRgbProfile = inputRgbProfile
' set output RGB profile
colorManagement.OutputRgbProfile = outputRgbProfile
' create decoding settings
If image.DecodingSettings Is Nothing Then
image.DecodingSettings = New Vintasoft.Imaging.Codecs.Decoders.DecodingSettings()
End If
' set color management settings
image.DecodingSettings.ColorManagement = colorManagement
' copy image with specified color management
Return DirectCast(image.Clone(), Vintasoft.Imaging.VintasoftImage)
End Function
Если есть необходимость использовать разные настройки управления цветом при декодировании одного и того же изображения, необходимо создать новое изображение как копию исходного изображения с помощью метода
VintasoftImage.CreateImageBasedOnSourceImageDecoder и назначить новые настройки декодирования и управления цветом для нового изображения
В следующем примере показано, как получить растровое изображение из объекта
VintasoftImage с настройками декодирования, отличными от настроек декодирования объекта
VintasoftImage:
/// <summary>
/// Returns a bitmap from image with specified color management settings.
/// </summary>
public Vintasoft.Imaging.VintasoftBitmap GetVintasoftBitmap(
Vintasoft.Imaging.VintasoftImage image,
Vintasoft.Imaging.ColorManagement.ColorManagementDecodeSettings colorManagement)
{
using (Vintasoft.Imaging.VintasoftImage tempImage =
Vintasoft.Imaging.VintasoftImage.CreateImageBasedOnSourceImageDecoder(image))
{
tempImage.DecodingSettings =
new Vintasoft.Imaging.Codecs.Decoders.DecodingSettings();
tempImage.DecodingSettings.ColorManagement = colorManagement;
return tempImage.GetAsVintasoftBitmap();
}
}
''' <summary>
''' Returns a bitmap from image with specified color management settings.
''' </summary>
Public Function GetVintasoftBitmap(image As Vintasoft.Imaging.VintasoftImage, colorManagement As Vintasoft.Imaging.ColorManagement.ColorManagementDecodeSettings) As Vintasoft.Imaging.VintasoftBitmap
Using tempImage As Vintasoft.Imaging.VintasoftImage = Vintasoft.Imaging.VintasoftImage.CreateImageBasedOnSourceImageDecoder(image)
tempImage.DecodingSettings = New Vintasoft.Imaging.Codecs.Decoders.DecodingSettings()
tempImage.DecodingSettings.ColorManagement = colorManagement
Return tempImage.GetAsVintasoftBitmap()
End Using
End Function
2.9. Включение управление цветом в просмотрщике изображений/миниатюр
Все UI-контролы для просмотр изображений и миниатюр (
ImageViewer,
WpfImageViewer,
ThumbnailViewer,
WpfThumbnailViewer,
AnnotationViewer,
WpfAnnotationViewer и т. д.) имеют встроенную поддержку управления цветом. Свойство
ImageViewerBase.ImageDecodingSettings определяет настройки декодирования изображения. Свойство
DecodingSettings.ColorManagement определяет настройки управления цветом изображения.
Важно:
Управление цветом невозможно применить к изображению на основе растрового объекта (свойству
VintasoftImage.HasBitmapData присвоено значение
True
).
В следующем примере показано, как включить или отключить управление цветом в просмотрщике изображений:
/// <summary>
/// Enables the color management in image or thumbnail viewer.
/// </summary>
/// <param name="viewer">An image/thumbnail viewer.</param>
/// <param name="inputCmykProfile">The input CMYK profile.</param>
/// <param name="inputRgbProfile">The input RGB profile.</param>
/// <param name="outputRgbProfile">The output RGB profile.</param>
public static void EnableViewerColorManagement(
Vintasoft.Imaging.UI.ImageViewerBase viewer,
string inputCmykProfile,
string inputRgbProfile,
string outputRgbProfile)
{
// if all profiles are empty
if (string.IsNullOrEmpty(inputCmykProfile) &&
string.IsNullOrEmpty(inputRgbProfile) &&
string.IsNullOrEmpty(outputRgbProfile))
return;
// get current image decoding settings from the viewer
Vintasoft.Imaging.Codecs.Decoders.DecodingSettings decodingImageSettings = viewer.ImageDecodingSettings;
// if viewer does not have image decoding settings
if (decodingImageSettings == null)
// create new image decoding settings
decodingImageSettings = new Vintasoft.Imaging.Codecs.Decoders.DecodingSettings();
// init the image decoding settings
InitDecodingSettings(decodingImageSettings, inputCmykProfile, inputRgbProfile, outputRgbProfile);
// set decoding settings to the viewer
viewer.ImageDecodingSettings = decodingImageSettings;
// reload images in viewer
ReloadViewerImages(viewer);
}
/// <summary>
/// Disables the color management in image/thumbnail viewer.
/// </summary>
/// <param name="viewer">An image/thumbnail viewer.</param>
public static void DisableViewerColorManagement(Vintasoft.Imaging.UI.ImageViewerBase viewer)
{
// get decoding settings from image/thumbnail viewer
Vintasoft.Imaging.Codecs.Decoders.DecodingSettings imageDecodingSettings = viewer.ImageDecodingSettings;
if (imageDecodingSettings == null)
return;
// destroy the image decoding settings
DestroyColorManagementDecodeSettings(imageDecodingSettings.ColorManagement);
imageDecodingSettings.ColorManagement = null;
// set decoding settings to the image/thumbnail viewer
viewer.ImageDecodingSettings = imageDecodingSettings;
// reload images in image/thumbnail viewer
ReloadViewerImages(viewer);
}
/// <summary>
/// Initializes the decoding settings.
/// </summary>
/// <param name="decodingSettings">Image decoding settings.</param>
/// <param name="inputCmykProfile">The input CMYK profile.</param>
/// <param name="inputRgbProfile">The input RGB profile.</param>
/// <param name="outputRgbProfile">The output RGB profile.</param>
static void InitDecodingSettings(
Vintasoft.Imaging.Codecs.Decoders.DecodingSettings decodingSettings,
string inputCmykProfile,
string inputRgbProfile,
string outputRgbProfile)
{
DestroyColorManagementDecodeSettings(decodingSettings.ColorManagement);
decodingSettings.ColorManagement = null;
decodingSettings.ColorManagement = new Vintasoft.Imaging.ColorManagement.ColorManagementDecodeSettings();
InitColorManagementDecodeSettings(decodingSettings.ColorManagement, inputCmykProfile, inputRgbProfile, outputRgbProfile);
}
/// <summary>
/// Destroys the color management decode settings.
/// </summary>
/// <param name="colorManagementDecodeSettings">Color management decode settings.</param>
static void DestroyColorManagementDecodeSettings(
Vintasoft.Imaging.ColorManagement.ColorManagementDecodeSettings colorManagementDecodeSettings)
{
if (colorManagementDecodeSettings != null)
{
// if input CMYK profile is not empty
if (colorManagementDecodeSettings.InputCmykProfile != null)
{
// remove input CMYK profile
colorManagementDecodeSettings.InputCmykProfile.Dispose();
}
// if input RGB profile is not empty
if (colorManagementDecodeSettings.InputRgbProfile != null)
{
// remove input RGB profile
colorManagementDecodeSettings.InputRgbProfile.Dispose();
}
// if output RGB profile is not empty
if (colorManagementDecodeSettings.OutputRgbProfile != null)
{
// remove output RGB profile
colorManagementDecodeSettings.OutputRgbProfile.Dispose();
}
}
}
/// <summary>
/// Initializes the color management decode settings.
/// </summary>
/// <param name="colorManagementDecodeSettings">Color management decode settings.</param>
/// <param name="inputCmykProfile">The input CMYK profile.</param>
/// <param name="inputRgbProfile">The input RGB profile.</param>
/// <param name="outputRgbProfile">The output RGB profile.</param>
static void InitColorManagementDecodeSettings(
Vintasoft.Imaging.ColorManagement.ColorManagementDecodeSettings colorManagementDecodeSettings,
string inputCmykProfile,
string inputRgbProfile,
string outputRgbProfile)
{
// if input CMYK profile is not empty
if (!string.IsNullOrEmpty(inputCmykProfile))
{
// set input CMYK profile
colorManagementDecodeSettings.InputCmykProfile =
new Vintasoft.Imaging.ColorManagement.Icc.IccProfile(inputCmykProfile);
}
// if input RGB profile is not empty
if (!string.IsNullOrEmpty(inputRgbProfile))
{
// set input RGB profile
colorManagementDecodeSettings.InputRgbProfile =
new Vintasoft.Imaging.ColorManagement.Icc.IccProfile(inputRgbProfile);
}
// if output RGB profile is not empty
if (!string.IsNullOrEmpty(outputRgbProfile))
{
// set output RGB profile
colorManagementDecodeSettings.OutputRgbProfile =
new Vintasoft.Imaging.ColorManagement.Icc.IccProfile(outputRgbProfile);
}
}
/// <summary>
/// Reloads the images in the specified image/thumbnail viewer.
/// </summary>
/// <param name="viewer">The image/thumbnail viewer.</param>
static void ReloadViewerImages(Vintasoft.Imaging.UI.ImageViewerBase viewer)
{
try
{
// get the image collection
Vintasoft.Imaging.ImageCollection images = viewer.Images;
// get the focused image
int focusedIndex = viewer.FocusedIndex;
Vintasoft.Imaging.VintasoftImage focusedImage = null;
if (focusedIndex >= 0 && focusedIndex < images.Count)
{
focusedImage = images[focusedIndex];
// if focused image is not empty
if (focusedImage != null)
{
// reload image
focusedImage.Reload(true);
}
}
// for each image in collection
foreach (Vintasoft.Imaging.VintasoftImage image in images)
{
// if this is not focused image
if (image != focusedImage)
{
// reload image
image.Reload(true);
}
}
}
catch (System.Exception ex)
{
// show error message
System.Windows.Forms.MessageBox.Show(ex.Message, "Error",
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error);
}
}
''' <summary>
''' Enables the color management in image or thumbnail viewer.
''' </summary>
''' <param name="viewer">An image/thumbnail viewer.</param>
''' <param name="inputCmykProfile">The input CMYK profile.</param>
''' <param name="inputRgbProfile">The input RGB profile.</param>
''' <param name="outputRgbProfile">The output RGB profile.</param>
Public Shared Sub EnableViewerColorManagement(viewer As Vintasoft.Imaging.UI.ImageViewerBase, inputCmykProfile As String, inputRgbProfile As String, outputRgbProfile As String)
' if all profiles are empty
If String.IsNullOrEmpty(inputCmykProfile) AndAlso String.IsNullOrEmpty(inputRgbProfile) AndAlso String.IsNullOrEmpty(outputRgbProfile) Then
Return
End If
' get current image decoding settings from the viewer
Dim decodingImageSettings As Vintasoft.Imaging.Codecs.Decoders.DecodingSettings = viewer.ImageDecodingSettings
' if viewer does not have image decoding settings
If decodingImageSettings Is Nothing Then
' create new image decoding settings
decodingImageSettings = New Vintasoft.Imaging.Codecs.Decoders.DecodingSettings()
End If
' init the image decoding settings
InitDecodingSettings(decodingImageSettings, inputCmykProfile, inputRgbProfile, outputRgbProfile)
' set decoding settings to the viewer
viewer.ImageDecodingSettings = decodingImageSettings
' reload images in viewer
ReloadViewerImages(viewer)
End Sub
''' <summary>
''' Disables the color management in image/thumbnail viewer.
''' </summary>
''' <param name="viewer">An image/thumbnail viewer.</param>
Public Shared Sub DisableViewerColorManagement(viewer As Vintasoft.Imaging.UI.ImageViewerBase)
' get decoding settings from image/thumbnail viewer
Dim imageDecodingSettings As Vintasoft.Imaging.Codecs.Decoders.DecodingSettings = viewer.ImageDecodingSettings
If imageDecodingSettings Is Nothing Then
Return
End If
' destroy the image decoding settings
DestroyColorManagementDecodeSettings(imageDecodingSettings.ColorManagement)
imageDecodingSettings.ColorManagement = Nothing
' set decoding settings to the image/thumbnail viewer
viewer.ImageDecodingSettings = imageDecodingSettings
' reload images in image/thumbnail viewer
ReloadViewerImages(viewer)
End Sub
''' <summary>
''' Initializes the decoding settings.
''' </summary>
''' <param name="decodingSettings">Image decoding settings.</param>
''' <param name="inputCmykProfile">The input CMYK profile.</param>
''' <param name="inputRgbProfile">The input RGB profile.</param>
''' <param name="outputRgbProfile">The output RGB profile.</param>
Private Shared Sub InitDecodingSettings(decodingSettings As Vintasoft.Imaging.Codecs.Decoders.DecodingSettings, inputCmykProfile As String, inputRgbProfile As String, outputRgbProfile As String)
DestroyColorManagementDecodeSettings(decodingSettings.ColorManagement)
decodingSettings.ColorManagement = Nothing
decodingSettings.ColorManagement = New Vintasoft.Imaging.ColorManagement.ColorManagementDecodeSettings()
InitColorManagementDecodeSettings(decodingSettings.ColorManagement, inputCmykProfile, inputRgbProfile, outputRgbProfile)
End Sub
''' <summary>
''' Destroys the color management decode settings.
''' </summary>
''' <param name="colorManagementDecodeSettings">Color management decode settings.</param>
Private Shared Sub DestroyColorManagementDecodeSettings(colorManagementDecodeSettings As Vintasoft.Imaging.ColorManagement.ColorManagementDecodeSettings)
If colorManagementDecodeSettings IsNot Nothing Then
' if input CMYK profile is not empty
If colorManagementDecodeSettings.InputCmykProfile IsNot Nothing Then
' remove input CMYK profile
colorManagementDecodeSettings.InputCmykProfile.Dispose()
End If
' if input RGB profile is not empty
If colorManagementDecodeSettings.InputRgbProfile IsNot Nothing Then
' remove input RGB profile
colorManagementDecodeSettings.InputRgbProfile.Dispose()
End If
' if output RGB profile is not empty
If colorManagementDecodeSettings.OutputRgbProfile IsNot Nothing Then
' remove output RGB profile
colorManagementDecodeSettings.OutputRgbProfile.Dispose()
End If
End If
End Sub
''' <summary>
''' Initializes the color management decode settings.
''' </summary>
''' <param name="colorManagementDecodeSettings">Color management decode settings.</param>
''' <param name="inputCmykProfile">The input CMYK profile.</param>
''' <param name="inputRgbProfile">The input RGB profile.</param>
''' <param name="outputRgbProfile">The output RGB profile.</param>
Private Shared Sub InitColorManagementDecodeSettings(colorManagementDecodeSettings As Vintasoft.Imaging.ColorManagement.ColorManagementDecodeSettings, inputCmykProfile As String, inputRgbProfile As String, outputRgbProfile As String)
' if input CMYK profile is not empty
If Not String.IsNullOrEmpty(inputCmykProfile) Then
' set input CMYK profile
colorManagementDecodeSettings.InputCmykProfile = New Vintasoft.Imaging.ColorManagement.Icc.IccProfile(inputCmykProfile)
End If
' if input RGB profile is not empty
If Not String.IsNullOrEmpty(inputRgbProfile) Then
' set input RGB profile
colorManagementDecodeSettings.InputRgbProfile = New Vintasoft.Imaging.ColorManagement.Icc.IccProfile(inputRgbProfile)
End If
' if output RGB profile is not empty
If Not String.IsNullOrEmpty(outputRgbProfile) Then
' set output RGB profile
colorManagementDecodeSettings.OutputRgbProfile = New Vintasoft.Imaging.ColorManagement.Icc.IccProfile(outputRgbProfile)
End If
End Sub
''' <summary>
''' Reloads the images in the specified image/thumbnail viewer.
''' </summary>
''' <param name="viewer">The image/thumbnail viewer.</param>
Private Shared Sub ReloadViewerImages(viewer As Vintasoft.Imaging.UI.ImageViewerBase)
Try
' get the image collection
Dim images As Vintasoft.Imaging.ImageCollection = viewer.Images
' get the focused image
Dim focusedIndex As Integer = viewer.FocusedIndex
Dim focusedImage As Vintasoft.Imaging.VintasoftImage = Nothing
If focusedIndex >= 0 AndAlso focusedIndex < images.Count Then
focusedImage = images(focusedIndex)
' if focused image is not empty
If focusedImage IsNot Nothing Then
' reload image
focusedImage.Reload(True)
End If
End If
' for each image in collection
For Each image As Vintasoft.Imaging.VintasoftImage In images
' if this is not focused image
If image IsNot focusedImage Then
' reload image
image.Reload(True)
End If
Next
Catch ex As System.Exception
' show error message
System.Windows.Forms.MessageBox.Show(ex.Message, "Error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.[Error])
End Try
End Sub
2.10. Включение управление цветом при получении изображения с помощью декодера
По умолчанию декодер (класс, производный от класса
DecoderBase) не использует управление цветом при получении изображения или миниатюры. Для получения изображения с включенным управлением цветом необходимо включить управление цветом с помощью параметра decodingSettings (типа
ColorManagementDecodeSettings) в методе
DecoderBase.GetImage. Для получения миниатюры с включенным управлением цветом необходимо включить управление цветом с помощью параметра decodingSettings (типа
ColorManagementDecodeSettings) в методе
DecoderBase.GetThumbnail.
В следующем примере показано, как включить управление цветом при получении изображения TIFF страницы:
/// <summary>
/// Returns an image of specified tiff page with enabled color management.
/// </summary>
public static Vintasoft.Imaging.VintasoftImage GetTiffPageWithColorManagement(
Vintasoft.Imaging.Codecs.ImageFiles.Tiff.TiffPage tiffPage,
System.EventHandler<Vintasoft.Imaging.ProgressEventArgs> progressDelegate)
{
// create decoding settings
Vintasoft.Imaging.Codecs.Decoders.DecodingSettings decodingSettings =
new Vintasoft.Imaging.Codecs.Decoders.DecodingSettings();
// enable color management
decodingSettings.ColorManagement =
new Vintasoft.Imaging.ColorManagement.ColorManagementDecodeSettings();
// get image of Tiff page
return tiffPage.GetImage(decodingSettings, progressDelegate);
}
''' <summary>
''' Returns an image of specified tiff page with enabled color management.
''' </summary>
Public Shared Function GetTiffPageWithColorManagement(tiffPage As Vintasoft.Imaging.Codecs.ImageFiles.Tiff.TiffPage, progressDelegate As System.EventHandler(Of Vintasoft.Imaging.ProgressEventArgs)) As Vintasoft.Imaging.VintasoftImage
' create decoding settings
Dim decodingSettings As New Vintasoft.Imaging.Codecs.Decoders.DecodingSettings()
' enable color management
decodingSettings.ColorManagement = New Vintasoft.Imaging.ColorManagement.ColorManagementDecodeSettings()
' get image of Tiff page
Return tiffPage.GetImage(decodingSettings, progressDelegate)
End Function
2.11. Оптимизация и потокобезопасность при преобразовании цветов
Оптимизация преобразований цветов необходима для повышения производительности составного преобразования цветов и может быть выполнена с помощью метода
ColorTransformsOptimizer.GetOptimizedTransform. Класс
ColorManagementDecodeSettings всегда возвращает оптимизированное цветовое преобразование, во всех остальных случаях может потребоваться оптимизация составного цветового преобразования.
Для оптимизации составного цветового преобразования класс
ColorTransformsOptimizer анализирует результаты выполнения методов
ColorTransform.IsIdentity,
ColorTransform.IsInverseTransform и
ColorTransform.CreateOptimizedWith цветового преобразования, которые состоят из оптимизированной трансформации.
-
ColorTransform.IsIdentity метод должен возвращать
True
только в том случае, если преобразование цвета идентично.
-
ColorTransform.IsInverseTransform метод должен возвращать
True
только в том случае, если преобразование цвета является обратным исходному, т.е. когда комбинация текущего преобразования с указанным является идентичным преобразованием.
-
ColorTransform.CreateOptimizedWith должен возвращать определенное преобразование цвета, отличное от
null
, только в том случае, если оно равно комбинации текущего и заданного преобразований, но имеет большую производительность. чем сама эта комбинация.
Значение преобразования, возвращаемое методом
ColorTransformsOptimizer.GetOptimizedTransform, может быть
null
, если оптимизированное преобразование цвета оказалось идентичным.
ColorTransform.IsThreadSafe определяет потокобезопасность текущего экземпляра класса
ColorTransform. Необходимость потокобезопасности вызвана использованием преобразований цвета в многопоточных задачах, например, при использовании многопоточности в некоторых декодерах. Однако если потокобезопасность не используется, это может повысить производительность. Например, составное преобразование
FastCompositeColorTransform использует буферы постоянной памяти, поэтому оно не является потокобезопасным, но более производительным, чем
SimpleCompositeColorTransform.
ColorTransformsOptimizer.GetOptimizedTransform метод с одним параметром всегда возвращает не оптимизированное потоко-безопасное цветовое преобразование. Метод
ColorTransformsOptimizer.GetOptimizedTransform с двумя параметрами, второй из которых является логическим параметром, возвращает оптимизированное потоко-безопасное цветовое преобразование, если для логического параметра установлено значение
True
, и возвращает оптимизированное не потоко-безопасное цветовое преобразование, если логический параметр установлен в
False
.
ColorTransformSet класс позволяет запретить добавление не потоко-безопасных цветовых преобразований в набор цветовых преобразований с помощью параметра конструктор. Если свойство
ColorTransformSet.IsThreadSafe имеет значение
True
, набор цветовых преобразований содержит только потоко-безопасные цветовые преобразования.
Экземпляр класса
ColorManagementDecodeSettings содержит только потоко-безопасные цветовые преобразования, однако в большинстве случаев методы получения цвтового преобразования класса
ColorManagementDecodeSettings возвращают не потоко-безопасное составное преобразование
FastCompositeColorTransform , состоящее из потоко-безопасных преобразований.
В следующем примере показано, как получить составное преобразование из указанных входных и выходных профилей ICC и оптимизировать преобразование:
/// <summary>
/// Creates a composite color transform from specified source and destination RGB profiles
/// and returns optimized thread-unsafe color transform.
/// </summary>
public static Vintasoft.Imaging.ColorManagement.ColorTransform GetOptimizedRgbTransform(
string sourceRgbProfileFilename, string destRgbProfileFilename)
{
// create ICC profiles
using (Vintasoft.Imaging.ColorManagement.Icc.IccProfile sourceIccProfile =
new Vintasoft.Imaging.ColorManagement.Icc.IccProfile(sourceRgbProfileFilename))
using (Vintasoft.Imaging.ColorManagement.Icc.IccProfile destIccProfile =
new Vintasoft.Imaging.ColorManagement.Icc.IccProfile(destRgbProfileFilename))
{
// check device color space of the source profile
if (sourceIccProfile.DeviceColorSpace != Vintasoft.Imaging.ColorSpaceType.sRGB)
{
throw new System.ArgumentException("Source profile is not RGB profile.");
}
// check device color space of the destination profile
if (destIccProfile.DeviceColorSpace != Vintasoft.Imaging.ColorSpaceType.sRGB)
{
throw new System.ArgumentException("Destination profile is not RGB profile.");
}
// get transforms from device color space to PCS
Vintasoft.Imaging.ColorManagement.ColorTransform deviceToPcsTransform = sourceIccProfile.GetDeviceToPcsTransform();
// get transforms from PCS to device color space
Vintasoft.Imaging.ColorManagement.ColorTransform pcsToDeviceTransform = destIccProfile.GetPcsToDeviceTransform();
// composite color transform
Vintasoft.Imaging.ColorManagement.ColorTransform composition;
if (sourceIccProfile.PcsColorSpace == destIccProfile.PcsColorSpace)
{
// create simple composite color transform
composition = Vintasoft.Imaging.ColorManagement.SimpleCompositeColorTransform.Create(
deviceToPcsTransform,
pcsToDeviceTransform);
}
else
{
if (sourceIccProfile.PcsColorSpace == Vintasoft.Imaging.ColorSpaceType.PCSXYZ)
{
// create simple composite color transform with intermediate PCSXYZ->PCSLab conversion
composition = Vintasoft.Imaging.ColorManagement.SimpleCompositeColorTransform.Create(
deviceToPcsTransform,
Vintasoft.Imaging.ColorManagement.ColorTransforms.PcsXyzToPcsLabD50,
pcsToDeviceTransform);
}
else
{
// create simple composite color transform with intermediate PCSLab->PCSXYZ conversion
composition = Vintasoft.Imaging.ColorManagement.SimpleCompositeColorTransform.Create(
deviceToPcsTransform,
Vintasoft.Imaging.ColorManagement.ColorTransforms.PcsLabToPcsXyzD50,
pcsToDeviceTransform);
}
}
// return optimized color transform
return Vintasoft.Imaging.ColorManagement.ColorTransformsOptimizer.GetOptimizedTransform(composition, false);
}
}
''' <summary>
''' Creates a composite color transform from specified source and destination RGB profiles
''' and returns optimized thread-unsafe color transform.
''' </summary>
Public Shared Function GetOptimizedRgbTransform(sourceRgbProfileFilename As String, destRgbProfileFilename As String) As Vintasoft.Imaging.ColorManagement.ColorTransform
' create ICC profiles
Using sourceIccProfile As New Vintasoft.Imaging.ColorManagement.Icc.IccProfile(sourceRgbProfileFilename)
Using destIccProfile As New Vintasoft.Imaging.ColorManagement.Icc.IccProfile(destRgbProfileFilename)
' check device color space of the source profile
If sourceIccProfile.DeviceColorSpace <> Vintasoft.Imaging.ColorSpaceType.sRGB Then
Throw New System.ArgumentException("Source profile is not RGB profile.")
End If
' check device color space of the destination profile
If destIccProfile.DeviceColorSpace <> Vintasoft.Imaging.ColorSpaceType.sRGB Then
Throw New System.ArgumentException("Destination profile is not RGB profile.")
End If
' get transforms from device color space to PCS
Dim deviceToPcsTransform As Vintasoft.Imaging.ColorManagement.ColorTransform = sourceIccProfile.GetDeviceToPcsTransform()
' get transforms from PCS to device color space
Dim pcsToDeviceTransform As Vintasoft.Imaging.ColorManagement.ColorTransform = destIccProfile.GetPcsToDeviceTransform()
' composite color transform
Dim composition As Vintasoft.Imaging.ColorManagement.ColorTransform
If sourceIccProfile.PcsColorSpace = destIccProfile.PcsColorSpace Then
' create simple composite color transform
composition = Vintasoft.Imaging.ColorManagement.SimpleCompositeColorTransform.Create(deviceToPcsTransform, pcsToDeviceTransform)
Else
If sourceIccProfile.PcsColorSpace = Vintasoft.Imaging.ColorSpaceType.PCSXYZ Then
' create simple composite color transform with intermediate PCSXYZ->PCSLab conversion
composition = Vintasoft.Imaging.ColorManagement.SimpleCompositeColorTransform.Create(deviceToPcsTransform, Vintasoft.Imaging.ColorManagement.ColorTransforms.PcsXyzToPcsLabD50, pcsToDeviceTransform)
Else
' create simple composite color transform with intermediate PCSLab->PCSXYZ conversion
composition = Vintasoft.Imaging.ColorManagement.SimpleCompositeColorTransform.Create(deviceToPcsTransform, Vintasoft.Imaging.ColorManagement.ColorTransforms.PcsLabToPcsXyzD50, pcsToDeviceTransform)
End If
End If
' return optimized color transform
Return Vintasoft.Imaging.ColorManagement.ColorTransformsOptimizer.GetOptimizedTransform(composition, False)
End Using
End Using
End Function