Работа с цветом в Core Graphics строится вокруг двух взаимосвязанных сущностей — CGColor и CGColorSpace. CGColor представляет конкретный цвет с компонентами, а CGColorSpace определяет модель интерпретации этих компонентов. По данным Apple Documentation (2026), Core Graphics поддерживает более 20 стандартных цветовых пространств, включая sRGB, Generic Gray и Generic CMYK. Понимание разницы между CGColor и CGColorSpace необходимо для корректной отрисовки графики на iOS и macOS.
Главное
CGColor — это фундаментальный объект Core Graphics, представляющий цвет. В структуре CGColor хранятся числовые значения цветовых компонент и ссылка на CGColorSpace — цветовое пространство, в котором эти компоненты интерпретируются. Без привязки к цветовому пространству числовые значения компонент не имеют смысла: значение (1.0, 0.0, 0.0) в RGB — это красный, а в CMYK — голубой (Cyan).
CGColorSpace — это объект, определяющий модель цвета и диапазон представимых значений (gamut). Цветовое пространство задаёт правила, по которым числовые компоненты превращаются в видимый цвет на конкретном устройстве вывода. Core Graphics поддерживает как стандартные ICC-профилированные пространства, так и пользовательские пространства, создаваемые через CGColorSpace с кастомными таблицами преобразования.
Архитектура разделения цвета и цветового пространства — ключевая особенность Core Graphics, отличающая её от API, где цвет хранится как простой набор чисел. Такой подход позволяет Core Graphics выполнять аппаратно-независимое управление цветом: один и тот же объект CGColor может быть корректно отображён на разных дисплеях благодаря автоматическому преобразованию компонент через профиль CGColorSpace.
Core Graphics реализует цвет через модель, основанную на ICC-профилях (International Color Consortium). Каждый CGColorSpace содержит ссылку на ICC-профиль — стандартизированное описание того, как цветовые компоненты преобразуются в CIE XYZ — аппаратно-независимое цветовое пространство. Это позволяет Core Graphics выполнять автоматическую колориметрическую компенсацию между разными экранами.
При создании CGColor через функцию CGColorCreate происходит захват компонент из переданного массива и привязка к указанному CGColorSpace. Core Graphics копирует компоненты во внутреннее представление и создаёт ассоциацию с цветовым пространством. После этого цвет готов к использованию в любой графической операции — заливка, обводка, градиент, тень.
На macOS управление цветом осуществляется через фреймворк ColorSync, интегрированный в Core Graphics. ColorSync отслеживает калибровку дисплея и автоматически преобразует компоненты из цветового пространства источника в пространство целевого устройства. На iOS управление цветом реализовано через Quartz Core с поддержкой широкого цветового охвата (Display P3), начиная с iPhone 7.
CGColorSpace поддерживает четыре базовые цветовые модели: RGB (DeviceRGB, sRGB, Display P3), Gray (DeviceGray), CMYK (DeviceCMYK) и Lab. Каждая модель определяет количество и смысл цветовых компонент. RGB использует три канала — красный, зелёный, синий; Gray — один канал яркости; CMYK — четыре канала для печати; Lab — три канала: яркость и две цветоразностные компоненты.
| Цветовая модель | Компоненты | Применение | CGColorSpace тип |
|---|---|---|---|
| RGB | Red, Green, Blue | Экраны, графика для iOS/macOS | kCGColorSpaceSRGB |
| Gray | White (один канал) | Чёрно-белая графика, тени | kCGColorSpaceGenericGray |
| CMYK | Cyan, Magenta, Yellow, Black | Печатная продукция, PDF | kCGColorSpaceGenericCMYK |
| Display P3 | R, G, B (широкий охват) | Современные iOS-устройства | kCGColorSpaceDisplayP3 |
DeviceRGB — это наиболее распространённое цветовое пространство Core Graphics по умолчанию. Оно использует цветовой охват стандартного LCD-дисплея без ICC-профилирования. При создании графического контекста UIView или NSView, Core Graphics автоматически назначает DeviceRGB в качестве цветового пространства по умолчанию. sRGB — ICC-профилированная версия с фиксированным охватом и гаммой, рекомендованная для веб-контента.
Display P3 — цветовое пространство, основанное на стандарте DCI-P3, используемое в современных iOS-устройствах с широкоцветными дисплеями. Оно охватывает примерно на 25% больше видимых цветов, чем sRGB, особенно в зелёной и красной областях спектра. Для работы с Display P3 на iOS используется константа kCGColorSpaceDisplayP3, доступная с iOS 9.3.
CGColor создаётся через функцию CGColorCreate, которая принимает CGColorSpace и массив компонент типа CGFloat. Количество компонент зависит от цветовой модели: для Gray — 1, для RGB — 3, для CMYK — 4. После создания CGColor является неизменяемым (immutable) объектом — изменить его компоненты нельзя, можно только создать новый цвет.
Core Graphics предоставляет также функцию CGColorCreateGenericRGB, CGColorCreateGenericGray и CGColorCreateGenericCMYK для создания цветов в стандартных (generic) цветовых пространствах. Эти функции упрощают код, избавляя от необходимости явно создавать CGColorSpace. Кроме того, в Quartz 2D определены константы основных цветов: kCGColorWhite, kCGColorBlack, kCGColorClear.
При создании цвета важен порядок задания компонент — он должен строго соответствовать порядку каналов, определённому моделью цветового пространства. RGB: красный (0.0–1.0), зелёный, синий, альфа (0.0–1.0). Gray: яркость, альфа. CMYK: голубой, пурпурный, жёлтый, чёрный, альфа. Нарушение порядка компонент приводит к некорректному отображению цвета без ошибки компиляции.
Альфа-канал — четвертый компонент (или второй для Gray), управляющий прозрачностью цвета. Значение 1.0 соответствует полной непрозрачности, 0.0 — полной прозрачности. Альфа-канал в CGColor является опциональным: функция CGColorGetAlpha возвращает текущее значение альфы, которое по умолчанию равно 1.0 при создании через базовые функции. При смешивании цветов Core Graphics использует альфа-композитинг по правилу Porter-Duff Source Over.
CGColorSpace создаётся через фабричные функции Core Graphics: CGColorSpaceCreateDeviceRGB, CGColorSpaceCreateDeviceGray, CGColorSpaceCreateDeviceCMYK или CGColorSpaceCreateWithName для именованных пространств (sRGB, Display P3, Generic Gray). Объект CGColorSpace является неизменяемым и потокобезопасным — один и тот же объект может использоваться в нескольких графических контекстах.
Core Graphics предоставляет несколько предопределённых цветовых пространств через именованные константы: kCGColorSpaceSRGB, kCGColorSpaceDisplayP3, kCGColorSpaceGenericGrayGamma2_2. Эти константы передаются в CGColorSpaceCreateWithName. Для устройств iOS с широким цветовым охватом рекомендуется использовать Display P3, так как sRGB может не полностью использовать возможности дисплея.
ICC-профили — это стандартизированные файлы, описывающие цветовые характеристики устройства. Core Graphics позволяет создавать CGColorSpace на основе произвольного ICC-профиля через CGColorSpaceCreateWithICCProfile. Это используется в профессиональных приложениях для фотопечати и препресса, где требуется точное соответствие определённому принтеру или монитору.
Core Graphics выполняет преобразование между цветовыми пространствами автоматически при отрисовке через функцию CGContextSetFillColorWithColor или CGContextSetStrokeColorWithColor. Если цветовое пространство графического контекста отличается от цветового пространства переданного CGColor, Quartz 2D выполняет конвертацию с использованием ICC-профилей обоих пространств.
Для явного преобразования цвета используется CGColorCreateCopyByMatchingToColorSpace — функция создаёт новый CGColor, компоненты которого пересчитаны из исходного пространства в целевое. По данным Apple Technical Note TN2313 (2024), при преобразовании из Display P3 в sRGB цвета за пределами охвата sRGB клиппируются, что приводит к потере насыщенности. Это особенно заметно на ярких зелёных и красных оттенках.
ColorSync на macOS обеспечивает системное управление цветом на уровне графического стека. Если приложение не задаёт явного цветового пространства, Core Graphics использует пространство дисплея, полученное от ColorSync. Это гарантирует, что цвета будут выглядеть одинаково на разных мониторах, даже если они используют разные цветовые профили.
Рассмотрим практические примеры создания и использования CGColor и CGColorSpace в iOS-приложении. Код написан на Swift с использованием Core Graphics функций.
В этом примере показано создание красного цвета в трёх разных цветовых пространствах. Несмотря на одинаковые RGB-компоненты, цвет будет выглядеть по-разному в зависимости от цветового охвата CGColorSpace.
import CoreGraphics
// Creating color in DeviceRGB
let rgbSpace = CGColorSpaceCreateDeviceRGB()
let redColor = CGColorCreate(rgbSpace, [1.0, 0.0, 0.0, 1.0])
// Creating color in Display P3
let p3Space = CGColorSpaceCreateWithName(kCGColorSpaceDisplayP3)
let p3RedColor = CGColorCreate(p3Space, [1.0, 0.0, 0.0, 1.0])
// Creating gray color
let graySpace = CGColorSpaceCreateDeviceGray()
let grayColor = CGColorCreate(graySpace, [0.5, 1.0])
В примере выполняется конвертация ярко-зелёного цвета из Display P3 в sRGB. При таком преобразовании цвета за пределами sRGB-охвата будут адаптированы, что может изменить оттенок.
let p3Space = CGColorSpaceCreateWithName(kCGColorSpaceDisplayP3)
let sRGBSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB)
// Bright green in Display P3 (outside sRGB gamut)
let p3Green = CGColorCreate(p3Space, [0.0, 1.0, 0.0, 1.0])
// Converting to sRGB
let srgbGreen = CGColorCreateCopyByMatchingToColorSpace(
sRGBSpace, p3Green, kCGRenderingIntentDefault
)
Этот пример демонстрирует рисовку закрашенного круга с использованием CGColor в кастомном UIView. Метод draw получает текущий графический контекст UIGraphicsGetCurrentContext, в котором задаётся цвет заливки.
class ColorView: UIView {
override func draw(rect: CGRect) {
guard let ctx = UIGraphicsGetCurrentContext()
else { return }
let rgbSpace = CGColorSpaceCreateDeviceRGB()
let blueColor = CGColorCreate(
rgbSpace,
[0.2, 0.4, 1.0, 1.0]
)
ctx.setFillColor(blueColor)
ctx.fillEllipse(in: CGRect(x: 50, y: 50,
width: 200, height: 200))
}
}
Часто задаваемые вопросы
CGColor — это низкоуровневое представление цвета из Core Graphics, используемое в C-стиле API. UIColor — это высокоуровневая обёртка UIKit, которая внутри хранит CGColor и добавляет поддержку различий в тёмном режиме (traitCollection). UIColor можно преобразовать в CGColor через свойство .cgColor.
Цветовое пространство определяет, как числовые компоненты интерпретируются в видимый цвет. Один и тот же набор чисел (1.0, 0.0, 0.0) означает красный в RGB, но голубой в CMYK. Без CGColorSpace Core Graphics не может корректно отобразить цвет на конкретном устройстве с его уникальными характеристиками дисплея.
На iOS графический контекст UIView по умолчанию создаётся с цветовым пространством DeviceRGB. На устройствах с широкоцветным дисплеем (iPad Pro 9.7 дюймов и новее, iPhone 7 и новее) доступно также Display P3, которое поддерживает на 25% больше цветов, чем стандартное sRGB.
Нет, CGColor является неизменяемым (immutable) объектом. Для получения цвета с другими компонентами необходимо создать новый CGColor через CGColorCreate. Это соответствует дизайну Core Graphics, где большинство объектов являются неизменяемыми для обеспечения потокобезопасности и предсказуемости отрисовки.
Для преобразования используйте CGColorCreateCopyByMatchingToColorSpace с целевым CMYK-пространством. Core Graphics выполнит преобразование через ICC-профили с учётом рендерингового интента. Выберите kCGRenderingIntentRelativeColorimetric для печати или kCGRenderingIntentPerceptual для фотореалистичных изображений.
Итоги
CGColorCreateCopyByMatchingToColorSpaceМы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также